我们有一个处理器将接收元素队列,并且对于每个元素,它将运行一些需要保证以顺序方式执行的操作。要对元素执行的每个操作都是Promise Task(http://blog.stephencleary.com/2014/04/a-tour-of-task-part-0-overview.html)。队列中每个元素的处理不需要等待前一个元素的完成。 可以假设动作的签名是这样的:
Task MyAwaitableMethod(int delay)
我看到的方式,问题可以简化为执行循环,循环内部,执行顺序操作,每次迭代都不应该阻塞。我正在研究两种方法: 1.
for (var i = 0; i < Iterations; i++)
{
Task.Run(async () => {
await MyAwaitableMethod(DelayInMilliseconds);
await MyAwaitableMethod(DelayInMilliseconds);
});
}
2
for (var i = 0; i < Iterations; i++)
{
MyAwaitableMethod(DelayInMilliseconds).ContinueWith(
antecedent => MyAwaitableMethod(DelayInMilliseconds));
}
我假设,假设行为是Promises,那么使用方法#2,创建的线程会更少,而不是Task.Run,我假设会创建更多的线程。但是在我运行的测试中,在执行大量迭代时为两者创建的线程数趋于相同,并且不依赖于给定的迭代次数。
这两种方法完全相同吗?或者你们有更好的建议?
编辑(改写问题) 这两种方法在线程数方面都是等价的吗?由于
答案 0 :(得分:1)
为什么不使用Task.WhenAll()
?
var tasks = new List<Task>();
for (var i = 0; i < Iterations; i++)
{
Task t = MyAwaitableMethod(DelayInMilliseconds);
tasks.Add(t);
}
await Task.WhenAll(tasks);
答案 1 :(得分:1)
async-await的部分优点是编写顺序异步代码。
如果不是异步,你会写:
for (var i = 0; i < Iterations; i++)
{
MyAwaitableMethod(DelayInMilliseconds);
MyAwaitableMethod(DelayInMilliseconds);
}
如果您希望它是异步的,只需写:
for (var i = 0; i < Iterations; i++)
{
await MyAwaitableMethod(DelayInMilliseconds);
await MyAwaitableMethod(DelayInMilliseconds);
}
您发布的代码不符合您在上一个项目之后处理每个项目的要求,因为您没有等待Task.Run
。