我剛開始探索PTL並有一個設計問題。並行任務庫WaitAny Design
我的情景: 我有一個URL列表,每個指向一個圖像。我希望每個圖像都可以並行下載。只要至少有一個圖像被下載,我想要執行一個方法來處理下載的圖像。該方法不應該並行 - 它應該是串行的。
我認爲以下方法可行,但我不確定這是否正確。因爲我有單獨的類來收集圖像和爲收集的圖像做「事情」,所以我最終傳遞了一系列任務,這似乎是錯誤的,因爲它暴露了圖像檢索的內部工作原理。但我不知道解決方法。實際上,這兩種方法都有更多,但這對此並不重要。只要知道他們真的不應該被集中到一個既能檢索圖像又能處理圖像的大型方法。
//From the Director class
Task<Image>[] downloadTasks = collector.RetrieveImages(listOfURLs);
for (int i = 0; i < listOfURLs.Count; i++)
{
//Wait for any of the remaining downloads to complete
int completedIndex = Task<Image>.WaitAny(downloadTasks);
Image completedImage = downloadTasks[completedIndex].Result;
//Now do something with the image (this "something" must happen serially)
//Uses the "Formatter" class to accomplish this let's say
}
///////////////////////////////////////////////////
//From the Collector class
public Task<Image>[] RetrieveImages(List<string> urls)
{
Task<Image>[] tasks = new Task<Image>[urls.Count];
int index = 0;
foreach (string url in urls)
{
string lambdaVar = url; //Required... Bleh
tasks[index] = Task<Image>.Factory.StartNew(() =>
{
using (WebClient client = new WebClient())
{
//TODO: Replace with live image locations
string fileName = String.Format("{0}.png", i);
client.DownloadFile(lambdaVar, Path.Combine(Application.StartupPath, fileName));
}
return Image.FromFile(Path.Combine(Application.StartupPath, fileName));
},
TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent);
index++;
}
return tasks;
}
知識一天的寶石。感謝Ade。很棒的信息 – 2012-02-10 17:27:13