以非阻塞方式执行顺序操作的建议,任务.运行vs任务与ContinueWith

本文关键字:任务 运行 vs ContinueWith 方式 顺序操作 执行 | 更新日期: 2023-09-27 18:12:17

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

我假设,给定的动作是承诺,与方法#2,将有更少的线程创建,而不是任务。运行,我认为这会创建更多的线程。但是在我运行的测试中,当执行大量迭代时,为两者创建的线程数往往是相同的,并且不依赖于给定的迭代次数。

两个方法是否完全相等?或者你们有更好的建议?

编辑(改写问题)这两种方法所需的线程数是否相等?

谢谢

以非阻塞方式执行顺序操作的建议,任务.运行vs任务与ContinueWith

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