并行执行任务 [英] Executing tasks in parallel
问题描述
好的,所以基本上我有很多任务(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 Task
s 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屋!