GUI task.wait与控制台或ThreadPool的死锁 - c#

我目前正在深入阅读C#(第3版),给出的警告之一是将GUI线程与task.wait一起使用是危险的,因为它可能导致死锁。但这不是ThreadPool或控制台的问题。我的问题是,为什么运行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,从而允许主线程完成其等待。

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

Task.IsCancelled不起作用 - c#

我有以下示例代码:static class Program { static void Main() { var cts = new CancellationTokenSource(); var task = Task.Factory.StartNew( () => { try { Console.WriteLine("Task: Runni…

什么是Java GUI - java

我离Java技术太远了。出于好奇,仅允许我们使用Java开发桌面应用程序(例如Windows窗体)的技术/ API /类的名称是什么?我听说了一个名为Swing的工具包。那是官方的GUI工具包,Swing有其他替代方法吗?Java中是否有与C#的WPF相对应的技术? 参考方案 Java Swing是最常用的Java GUI工具包。有其他选择(JavaFX,A…

免费的Java GUI Builder? - java

我不喜欢使用布局管理器。我永远做不到任何正确的事情……所以……有人可以向我建议免费的applet GUI生成器吗?不要建议使用Eclipse或Netbeans,因为我有Vista(64位)。我不能跑他们=(谢谢! 参考方案 NetBeans可以在64位窗口上most certainly be installed,但是6.0.x版本需要32位JVM。似乎不再是…

在Spring中实例化一个新线程以定期执行任务 - java

我有一个用Spring制作的仪表板,它必须控制某些任务的执行。基本思想是有一个线程将该任务定期发送到远程跟踪器。如何实例化该线程?我已经阅读了一些,有人说使用线程不是一个好主意。这会导致Spring生命周期出现问题吗?还有另一种方法可以使方法定期调用吗? 参考方案 Spring支持任务计划。在此处查找更多信息:http://static.springsour…

从具有返回类型Task的方法返回值 - c#

我可能在这里错过了一些东西。语法不正确。static Task<int> MathOperation(int number) { //return new Task(new Func(TestMethod(number))); } static int LongRunningMethod(int number) { // some long ru…