并行执行任务 [英] Executing tasks in parallel

查看:121
本文介绍了并行执行任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,所以基本上我有很多任务(10),我想同时启动所有任务并等待它们完成。完成后,我想执行其他任务。我读了很多相关的资源,但是我无法解决我的特殊情况...

Ok, so basically I have a bunch of tasks (10) and I want to start them all at the same time and wait for them to complete. When completed I want to execute other tasks. I read a bunch of resources about this but I can't get it right for my particular case...

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

Here is what I currently have (code has been simplified):

public async Task RunTasks()
{
    var tasks = new List<Task>
    {
        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 调用完成的任务,它告诉我所有任务都已结束,即使它们都没有完成。我尝试在 foreach 中添加 Console.WriteLine ,当我输入了继续任务时,数据不断从我的先前尚未完成的任务

So my problem is that when I'm waiting for tasks to complete with the WhenAll call, it tells me that all tasks are over even though none of them are completed. I tried adding Console.WriteLine in my foreach and when I have entered the continuation task, data keeps coming in from my previous Tasks that aren't really finished.

我在这里做错什么了?

推荐答案

几乎应该永远不要直接使用 Task 构造函数。对于您来说,该任务只会触发您迫不及待的实际任务。

You should almost never use the Task constructor directly. In your case that task only fires the actual task that you can't wait for.

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

You can simply call DoWork and get back a task, store it in a list and wait for all the tasks to complete. Meaning:

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

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

However, async methods run synchronously until the first await on an uncompleted task is reached. If you worry about that part taking too long then use Task.Run to offload it to another ThreadPool thread and then store that task in the list:

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

这篇关于并行执行任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆