考虑一下,对于N个元素,我们有2个I / O绑定任务需要处理。我们可以将这两个任务称为 A 和 B 。 B 只能在 A 产生结果之后运行。
我们可以通过两种方式完成此任务。 (请忽略访问修改后的闭包的情况。)
Task.Run方式:
List<Task> workers = new List<Task>();
for (int i = 0; i < N; i++)
{
workers.Add(Task.Run(async () =>
{
await A(i);
await B(i);
}
}
await Task.WhenAll(workers);
经典Fork / Join:
List<Task> workersA = new List<Task>();
List<Task> workersB = new List<Task>();
for (int i = 0; i < N; i++)
{
workersA.Add(A(i));
}
await Task.WhenAll(workersA);
for (int i = 0; i < N; i++)
{
workersB.Add(B(i));
}
await Task.WhenAll(workersB);
或者,也可以通过以下方式完成此操作:
List<Task> workers = new List<Task>();
for (int i = 0; i < N; i++)
{
workers.Add(A(i));
}
for (int i = 0; i < N; i++)
{
await workers[i];
workers[i] = B(i);
}
await Task.WhenAll(workers);
我担心的是following MSDN文档指出,我们永远不要对I / O操作使用Task.Run。
考虑到这一点,那么处理这种情况的最佳方法是什么?
如果我错了,请更正我,但是我们要避免使用Task.Run,因为我们有效地将线程排队以处理工作,如果我们仅使用await,则在那里won't be any thread。 (由于操作是I / O。)
我真的很想走Task.Run路线,但是如果它最终由于没有明显的原因而使用线程/增加了额外的开销,那么那就不行了。