gpt4 book ai didi

c# - 为什么 Task.WhenAll(taskList) 不起作用?

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

如果 foreach 中的任务不是 async,则使 ping.Send 而不是ping.SendPingAsync 然后 Task.WhenAll(taskList) 将起作用。

List<Task> taskList = new List<Task>();   

foreach (var host in hostArray)
{
var aHost = host;
Task task = new Task(async ()=>
{
Ping ping = new Ping();
PingResult pingRes = new PingResult { HostNameOrAddress = aHost };
for (int i = 0; i < _pingCount; i++)
{
try
{
PingReply reply = await ping.SendPingAsync(aHost,1000);
if (reply.Status == IPStatus.Success)
pingRes.RoundtripTimes.Add(reply.RoundtripTime);
}
catch
{
// ignored
}
}

Dispatcher.Invoke(() =>
{
_pingResultList.Add(pingRes);
});
});

taskList.Add(task);
task.Start();
}

await Task.WhenAll(taskList); //Never wait.

最佳答案

不要使用任务的构造函数。它不支持异步 lambda。而是使用 Task.Run .

您的代码目前只等到您的 SendPingAsync在您的任务中调用,而不是为了完成整个异步方法。因为一旦第一个等待点命中,异步方法就会返回。

您的异步 lambda 编译为 Task(Action)这意味着它被编译为 async void 方法。由于没有简单的方法来等待 async void 方法,因此 Task 类构造函数不支持它。反之Task.Run通过 Task.Run(Func<Task>) overload 支持异步方法.因为这会返回一个 Task , Run 方法可以轻松等待其完成。

不仅用异步方法,总是喜欢Task.RunTask.Factory.StartNew (如果您需要更多控制)。几乎没有理由使用 Task构造函数。

如果您决定使用 StartNew对于异步方法,您必须调用 Task.UnWrap并等待它返回的任务。当您使用 Task.Run 时,您可以免费获得它。

关于c# - 为什么 Task.WhenAll(taskList) 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29865330/

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