gpt4 book ai didi

c# - GUI task.wait 与控制台或线程池的死锁

转载 作者:行者123 更新时间:2023-12-04 19:52:02 27 4
gpt4 key购买 nike

我目前正在深入阅读 C#(第 3 版),给出的警告之一是将 GUI 线程与 task.wait 一起使用是危险的,因为它可能会导致死锁。但它不是 ThreadPool 或 Console 的问题。我的问题是为什么运行 task.wait 的线程不会死锁,所以对于以下代码(摘自书中),即使是控制台应用程序(后台)线程也不会进入捕获状态,因为它会死锁。

public static void Main(string[] args = null)
{
var source = new CancellationTokenSource();
var task = TestInt(source.Token);
source.CancelAfter(4000);
Console.WriteLine("Status {0}",task.Status);
try
{
task.Wait();
}
catch (AggregateException e)
{
Console.WriteLine("Caught {0}",e.InnerExceptions[0]);
}
Console.WriteLine("Final Status: {0}",task.Status);
Console.ReadKey();
}

public static async Task TestInt(CancellationToken token, double start = 1)
{

await Task.Delay(TimeSpan.FromSeconds(30), token);
}

谢谢你

最佳答案

我详细解释一下in a blog post .

发生的事情是(默认情况下)await 将捕获当前“上下文”并使用该上下文来恢复执行 async 方法。这个“上下文”是 SynchronizationContext.Current 除非它是 null,在这种情况下它是 TaskScheduler.Current

在您的示例中,SynchronizationContext.Currentnull 并且 TaskScheduler.CurrentTaskScheduler.Default,即是,线程池任务调度器。因此,async 方法在线程池线程上恢复并且没有死锁。线程池线程完成async方法,完成Task,让主线程完成等待。

(在死锁情况下,有一个代表 UI 线程的 SynchronizationContext,因此 async 方法尝试在 UI 线程上恢复,但 UI 线程被调用阻塞等待)。

关于c# - GUI task.wait 与控制台或线程池的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19707656/

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