当前位置:  开发笔记 > 编程语言 > 正文

并行执行任务

如何解决《并行执行任务》经验,为你挑选了3个好方法。

好吧,基本上我有一堆任务(10),我想同时启动它们并等待它们完成.完成后我想执行其他任务.我读了很多关于这方面的资源,但我无法理解我的具体案例......

这是我目前拥有的(代码已经简化):

public async Task RunTasks()
{
    var tasks = new List
    {
        new Task(async () => await DoWork()),
        //and so on with the other 9 similar tasks
    }


    Parallel.ForEach(tasks, task =>
    {
        task.Start();
    });

    Task.WhenAll(tasks).ContinueWith(done =>
    {
        //Run the other tasks
    });
}

//This function perform some I/O operations
public async Task DoWork()
{
    var results = await GetDataFromDatabaseAsync();
    foreach (var result in results)
    {
        await ReadFromNetwork(result.Url);
    }
}

所以我的问题是,当我等待任务完成时WhenAll,它告诉我所有任务都已结束,即使它们都没有完成.我尝试添加Console.WriteLine我的内容foreach,当我进入延续任务时,数据不断从我以前的Tasks中进入,并没有真正完成.

我在这做错了什么?



1> i3arnon..:

你几乎不应该Task直接使用构造函数.在您的情况下,该任务仅触发您不能等待的实际任务.

您只需调用DoWork并获取任务,将其存储在列表中并等待所有任务完成.含义:

tasks.Add(DoWork());
// ...
await Task.WhenAll(tasks);

但是,异步方法同步运行,直到达到未完成任务的第一个等待.如果您担心该部分耗时太长,则使用Task.Run将其卸载到另一个ThreadPool线程,然后将该任务存储在列表中:

tasks.Add(Task.Run(() => DoWork()));
// ...
await Task.WhenAll(tasks);



2> sellotape..:

基本上你是在混合两种不兼容的异步范式; 即Parallel.ForEach()async-await.

为了你想要的,做一个或另一个.例如,你可以完全使用Parallel.For[Each]()和删除async-await. Parallel.For[Each]()只有在所有并行任务完成后才会返回,然后您可以转到其他任务.

代码也有一些其他问题:

你将方法标记为异步但不等待它(等待你在委托中,而不是方法);

你几乎肯定想要.ConfigureAwait(false)等待,特别是如果你不想在UI线程中立即使用结果.



3> Andrey Trety..:

如果要使用TPL在不同的线程中并行运行这些任务,则可能需要以下内容:

public async Task RunTasks()
{
    var tasks = new List>
    {
       DoWork,
       //...
    };

    await Task.WhenAll(tasks.AsParallel().Select(async task => await task()));

    //Run the other tasks
}

这些方法仅并行处理少量代码:方法排队到线程池和未完成的返回Task。同样,对于如此少量的任务,并行化可能要比异步运行花费更多的时间。仅当您的任务在第一次等待之前做一些更长的(同步)工作时,这才有意义。

在大多数情况下,更好的方法是:

public async Task RunTasks()
{
    await Task.WhenAll(new [] 
    {
        DoWork(),
        //...
    });
    //Run the other tasks
}

在您的代码中,我认为:

    Task在传递给之前,您不应包装代码Parallel.ForEach

    您可以await Task.WhenAll代替使用ContinueWith

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有