gpt4 book ai didi

c# - 如何等待异步任务

转载 作者:太空宇宙 更新时间:2023-11-03 17:48:46 26 4
gpt4 key购买 nike

static void Main(string[] args)
{
Action myAction = async () =>
{
await Task.Delay(5);
Console.WriteLine(Interlocked.Add(ref ExecutionCounter, 1));
};

var actions = new[] { myAction, myAction, myAction };

Task.WaitAll(actions.Select(a => Execute(a)).ToArray()); //This blocks, right?

Console.WriteLine("Done waiting on tasks.");
Console.ReadLine();
}

static int ExecutionCounter = 0;

private static Task Execute(Action a)
{
return Task.Factory.StartNew(async () =>
{
await Task.Delay(5);
a();
});
}

这看起来很简单,但自然地,输出总是看起来像这样(当然,数字的顺序会改变):

Done waiting on tasks.

2

1

3

我在这里错过了什么?为什么 Task.WaitAll 没有像我期望的那样阻塞?

最佳答案

所以这里有几个独立的错误。

首先,对于 Execute , 你正在使用 StartNewasync lambda 。自 StartNew没有 Task<Task>返回过载,如 Task.Run确实,您有一个返回 Task 的方法指示异步操作何时完成开始,而不是异步操作何时完成,这意味着 TaskExecute 返回基本上马上就完成,而不是在Delay之后完成或您调用的操作完成。此外,根本没有理由使用 StartNewRun在运行异步方法时,您可以正常执行它们并且 await无需将它们推送到线程池线程。

接下来,Execute接受 Action ,这意味着它是一种不计算任何值的同步方法。您提供的是一个异步 方法,但由于委托(delegate)不返回 Task , Execute不能await它。如果你想要Execute要处理异步方法,它需要接受一个返回 Task 的委托(delegate).

所以鉴于所有这些Execute应该看起来像这样。

private static async Task Execute(Func<Task> action)
{
await Task.Delay(TimeSpan.FromMilliseconds(5));
await action();
}

接下来是 Main方法。如前所述Execute正在接受 Action当您尝试提供 async方法。这意味着当操作运行时,代码将在您的操作完成之前继续执行。您需要将其调整为使用 Task返回方式。

在所有之后,您的代码在概念层面上仍然存在竞争条件,这将阻止您在理论上以正确的顺序获得结果。您并行执行 3 个不同的操作,因此,它们可以按任何顺序完成。当您以原子方式递增计数器时,一个线程可以递增计数器,然后另一个线程运行,递增计数器,打印它的值,然后让另一个线程再次运行并打印出值,给你一个可能的输出你所拥有的,即使在修复了上面提到的所有错误之后。为确保值按顺序打印,您需要确保增量和控制台写入以原子方式执行

现在你可以写出你的 Main像这样的方法:

int ExecutionCounter = 0;
object key = new object();
Func<Task> myAction = async () =>
{
await Task.Delay(TimeSpan.FromMilliseconds(5));
lock (key)
{
Console.WriteLine(++ExecutionCounter);
}
};

var actions = new[] { myAction, myAction, myAction };

Task.WaitAll(actions.Select(a => Execute(a)).ToArray()); //This blocks, right?

是的,正如您的评论所述,调用 WaitAll将阻塞,而不是异步。

关于c# - 如何等待异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44286456/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com