gpt4 book ai didi

c# - Task.WhenAll 未完成

转载 作者:行者123 更新时间:2023-12-03 13:19:03 36 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





An async/await example that causes a deadlock

(5 个回答)


4年前关闭。




我是 C# 任务的新手,遇到了一个我不理解的问题。在下面的代码中,有人可以解释为什么 Unsubscribe 方法末尾的 WriteLine 永远不会被调用。它似乎与前面的 foreach 循环中的 ContinueWith 相关,就好像我评论它工作正常一样。
谢谢

using System;
using System.Threading;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;

public class Example
{
public static void Main()
{

Task.Run(() => Unsubscribe());

Console.WriteLine("Method: Main. End");

Console.ReadKey();

}

private static void Unsubscribe()
{
Dictionary<int, string> dicPairsBySubID = new Dictionary<int, string>();

dicPairsBySubID.Add(1, "A");
dicPairsBySubID.Add(2, "B");
dicPairsBySubID.Add(3, "C");
dicPairsBySubID.Add(4, "D");
dicPairsBySubID.Add(5, "E");

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

foreach (KeyValuePair<int, string> sub in dicPairsBySubID)
{
int chanID = sub.Key;

Task task = Task.Run(() => SendUnsubscribe(chanID))
.ContinueWith(tsk =>
{
var flattened = tsk.Exception.Flatten();

flattened.Handle(ex =>
{
Console.WriteLine(string.Format("Error unsubscribing pair {0} (chanID = {2})", sub.Value, chanID), ex);
return true;
});

}, TaskContinuationOptions.OnlyOnFaulted);

taskList.Add(task);
}

Task.WhenAll(taskList).Wait();

// WHY DOES THIS NEVER GET RUN?
Console.WriteLine("Method: Unsubscribe. End");


}

private static async Task SendUnsubscribe(int chanID)
{


await SendAsync(chanID);


Console.WriteLine("Method: SendUnsubscribe. Chan ID: " + chanID);


}

private static async Task SendAsync(int chanID)
{

await Task.Run(() => Thread.Sleep(1000));
Console.WriteLine("Method: SendAsync. Chan ID: " + chanID);

}


}

最佳答案

您的任务引发了您没有捕获的异常,因为:

  • ContinueWith还返回一个任务(然后放置在 taskList 中)
  • 您已声明该任务仅应在前一个出现故障时运行(由于 TaskContinuationOptions.OnlyOnFaulted )
  • 您给出的示例没有进入故障状态。
  • 当 ContinueWith 任务由于这些选项而未运行时,enters the state Cancelled
  • 等待取消的任务会引发异常
  • 在您的 Main 方法中,Task.Run(() => Unsubscribe()) 的返回值调用不是 await ed,因此它从未被注意到。

  • 进一步:
  • 你不应该使用 Wait()关于任务。您已经开始使用asyncawait ,通过你的程序使用它。
    真正使用Wait()的唯一理由是你肯定不能使用异步的时候。尽量避免它。
  • 始终使用后缀 Async 命名您的方法当他们是async .这显示了使用该方法的用户的明确意图。
  • 关于c# - Task.WhenAll 未完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48326189/

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