简体   繁体   English

任务-财产分配

[英]Task - Property Assignment

Originally, I had the following: 最初,我有以下几点:

foreach (Product product in products)
{
    product.ImageUri = _imageClient.GetImageUri(product.GetImagePath());
}

What I would like to do is process all of the Products in parallel rather than one at a time. 我想做的是并行处理所有产品,而不是一次处理。 I have updated _imageClient.GetImageUri(...) to _imageClient.GetImageUriAsync(...). 我已经将_imageClient.GetImageUri(...)更新为_imageClient.GetImageUriAsync(...)。 I can now do the following: 我现在可以执行以下操作:

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);

The problem I have with this approach is that I now have to loop through the results, match each to the correct Product and assign the property. 这种方法的问题在于,我现在必须遍历结果,将每个结果与正确的Product匹配并分配属性。

Is there a way to combine the two approaches so that I can perform the property assignment as part of the task so that all can be run in parallel? 有没有一种方法可以将这两种方法结合起来,以便我可以将属性分配作为任务的一部分,以便所有这些都可以并行运行?

What about: 关于什么:

    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);    

You don't even really need the results in the end. 您甚至根本不需要最终结果。

you could start them also in a single select statement and await them in the same line: 您也可以在单个select语句中启动它们,然后在同一行中等待它们:

await Task.WhenAll(products.Select(async p => p.ImageUri = await _imageClient.GetImageUriAsync(p.GetImagePath())));

This will execute all tasks in parallel and initialize the property. 这将并行执行所有任务并初始化属性。 Task.WhenAll will then wait for the slowest of them. Task.WhenAll然后将等待它们中最慢的一个。

Here is a LINQPad Example to demonstrate the workings: 这是一个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; }
}

Output: 输出:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM