C# GUI任务的死锁。等待vs控制台或线程池

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

我目前正在深入阅读C#depth(第三版),其中一个警告是,在task.wait中使用GUI线程是危险的,因为它可能导致死锁。但这不是线程池或控制台的问题。我的问题是,为什么运行task.wait的线程没有死锁,所以对于下面的代码(取自本书),即使是控制台应用程序(backround)线程也不会像死锁一样到达捕获点

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
阻塞。)

我已经解释过了,谢谢你的回答和你博客的链接,它似乎有大量的线程和同步帖子。