C# GUI任务的死锁。等待vs控制台或线程池
我目前正在深入阅读C#depth(第三版),其中一个警告是,在task.wait中使用GUI线程是危险的,因为它可能导致死锁。但这不是线程池或控制台的问题。我的问题是,为什么运行task.wait的线程没有死锁,所以对于下面的代码(取自本书),即使是控制台应用程序(backround)线程也不会像死锁一样到达捕获点C# GUI任务的死锁。等待vs控制台或线程池,c#,task,C#,Task,我目前正在深入阅读C#depth(第三版),其中一个警告是,在task.wait中使用GUI线程是危险的,因为它可能导致死锁。但这不是线程池或控制台的问题。我的问题是,为什么运行task.wait的线程没有死锁,所以对于下面的代码(取自本书),即使是控制台应用程序(backround)线程也不会像死锁一样到达捕获点 public static void Main(string[] args = null) { var source = new CancellationTokenS
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);
}
谢谢你我会详细解释的
默认情况下,await
将捕获当前“上下文”,并使用该上下文来恢复async
方法的执行。此“上下文”是SynchronizationContext.Current
,除非它是null
,在这种情况下它是TaskScheduler.Current
在您的示例中,SynchronizationContext.Current
为null
和TaskScheduler.Current
为TaskScheduler.Default
,即线程池任务计划程序。因此,在线程池线程上恢复async
方法,并且没有死锁。线程池线程完成async
方法,完成任务
,允许主线程完成等待
(在死锁情况下,有一个表示UI线程的
SynchronizationContext
,因此async
方法尝试在UI线程上恢复,但UI线程被调用Wait
阻塞。)我已经解释过了,谢谢你的回答和你博客的链接,它似乎有大量的线程和同步帖子。