[英]Task - Property Assignment
最初,我有以下幾點:
foreach (Product product in products)
{
product.ImageUri = _imageClient.GetImageUri(product.GetImagePath());
}
我想做的是並行處理所有產品,而不是一次處理。 我已經將_imageClient.GetImageUri(...)更新為_imageClient.GetImageUriAsync(...)。 我現在可以執行以下操作:
List<Task<Uri>> tasks = new List<Task<Uri>>();
foreach (Product product in products)
{
Task<Uri> task = _imageClient.GetImageUriAsync(product.GetImagePath());
tasks.Add(task);
}
var results = await Task.WhenAll(tasks);
這種方法的問題在於,我現在必須遍歷結果,將每個結果與正確的Product匹配並分配屬性。
有沒有一種方法可以將這兩種方法結合起來,以便我可以將屬性分配作為任務的一部分,以便所有這些都可以並行運行?
關於什么:
List<Task<Uri>> tasks = new List<Task<Uri>>();
foreach (Product product in products)
{
tasks.Add(Task.Run( async () => product.ImageUri = await _imageClient.GetImageUriAsync(product.GetImagePath()) ));
}
await Task.WhenAll(tasks);
您甚至根本不需要最終結果。
您也可以在單個select語句中啟動它們,然后在同一行中等待它們:
await Task.WhenAll(products.Select(async p => p.ImageUri = await _imageClient.GetImageUriAsync(p.GetImagePath())));
這將並行執行所有任務並初始化屬性。 Task.WhenAll然后將等待它們中最慢的一個。
這是一個LINQPad示例,以演示其工作原理:
void Main()
{
Do();
}
public async Task Do()
{
List<Product> products = new List<UserQuery.Product>
{
new Product(),
new Product(),
new Product(),
new Product(),
};
Stopwatch sw = new Stopwatch();
Console.WriteLine("START");
sw.Start();
await Task.WhenAll(products.Select(async x => x.MyProperty = await GetNumber()));
sw.Stop();
Console.WriteLine($"ENDE: {sw.ElapsedMilliseconds}");
products.Dump();
}
public async Task<int> GetNumber()
{
Random rand = new Random(DateTime.Now.Millisecond);
return await Task.Run(() => { System.Threading.Thread.Sleep(4000); return rand.Next(1,1000);});
}
class Product
{
public int MyProperty { get; set; }
}
輸出:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.