关于以非阻塞方式执行顺序操作的建议,Task.Run vs 使用 ContinueWith 的任务

Advice on executing sequential operations in a non-blocking manner, Task.Run vs task with ContinueWith

我们有一个处理器将接收一个元素队列,对于每个元素,它将运行一些需要保证按顺序执行的操作。在元素上执行的每个操作都是一个 Promise 任务 (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));
}

我假设,鉴于操作是承诺,使用方法 #2,创建的线程会更少,而不是 Task.Run,我假设会创建更多线程。但是在我的测试中 运行,当执行大量迭代时为两者创建的线程数往往是相同的,并且不依赖于给定的迭代次数。

这两种方法是否完全等同?或者大家有更好的建议吗?

编辑(改写问题) 这两种方法在线程数方面是否相同?

谢谢

为什么不使用 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);

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