[英]How can I refactor this ForEach(..) code to use Parallel.ForEach(..)?
我有一個對象列表,希望將其從一個來源復制到另一個來源。 有人建議我可以使用Parallel.ForEach 加快速度
我如何重構以下pseduo代碼以利用Parallel.ForEach(..)
?
var foos = GetFoos().ToList();
foreach(var foo in foos)
{
CopyObjectFromOldBucketToNewBucket(foo, oldBucket, newBucket,
accessKeyId, secretAccessKey);
}
CopyObjectFromOldBucketToNewBucket
使用Amazon REST API將項目從一個存儲桶移動到另一個存儲桶。
干杯:)
由於您的代碼除了對foos
之外沒有任何依賴關系,您可以簡單地執行以下操作:
Parallel.ForEach(foos, ( foo =>
{
CopyObjectFromOldBucketToNewBucket(foo, oldBucket, newBucket,
accessKeyId, secretAccessKey);
}));
但是請記住,在性能可能實際下降之后,I / O只能並行到一定程度。
實際上, Parallel
並不是此處的最佳選擇。 Parallel
將Parallel
運行您的代碼,但仍將為每個對AWS的請求使用線程池線程。 最好使用資源來代替使用BeginCopyObject
方法。 這不會耗盡等待響應的線程池線程,而只會在接收到響應並需要對其進行處理時才使用它。
這是有關如何使用Begin / End方法的簡化示例。 這些不是特定於AWS的,而是在整個.NET BCL中找到的一種模式。
public static CopyFoos()
{
var client = new AmazonS3Client(...);
var foos = GetFoos().ToList();
var asyncs = new List<IAsyncResult>();
foreach(var foo in foos)
{
var request = new CopyObjectRequest { ... };
asyncs.Add(client.BeginCopyObject(request, EndCopy, client));
}
foreach(IAsyncResult ar in asyncs)
{
if (!ar.IsCompleted)
{
ar.AsyncWaitHandle.WaitOne();
}
}
}
private static EndCopy(IAsyncRequest ar)
{
((AmazonS3Client)ar.AsyncState).EndCopyObject(ar);
}
對於生產代碼,您可能希望跟蹤已發出的請求數量,並且一次只能發送有限數量的請求。 測試或AWS文檔可能會告訴您有多少並發請求是最佳的。
在這種情況下,當請求完成時,我們實際上不需要執行任何操作,因此您可能會想跳過EndCopy
調用,但這會導致資源泄漏。 每當調用BeginXxx時,都必須調用相應的EndXxx方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.