为什么在直接在Main()中启动表单时,Task.WaitAll会挂起?

时间:2018-05-08 21:49:15

标签: c# winforms task message-loop

我已经在C#WinForms应用程序中添加了一个启动屏幕表单,以便在应用程序初始化/检查更新时显示。我使用Squirrel.Windows检查Program.cs中的更新。

添加启动画面后,Main()中对Task.WaitAll的调用永远不会返回。在添加启动画面之前,此调用按预期工作。

如果在前台显示启动画面时,我该怎么做才能确保任务在Main()中完成?

工作示例:

static void Main()
    {
        try
        {
            using (var mgr = new UpdateManager("xxxx"))
            {
                var task = mgr.UpdateApp();
                task.RunSynchronously();
                Task.WaitAll(task);
                Console.WriteLine(task.Status);
            }
        }
        catch (Exception ex)
        {
            logger.Debug(ex.Message);
        }

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new XForm());
    }

非工作示例:

static void Main()
    {
        var ss = new SplashScreen();
        Application.Run(ss);
        try
        {
            using (var mgr = new UpdateManager("xxxx"))
            {
                var task = mgr.UpdateApp();
                task.RunSynchronously();
                Task.WaitAll(task);
                Console.WriteLine(task.Status);
            }
        }
        catch (Exception ex)
        {
            logger.Debug(ex.Message);
        }
        ss.Close(); 
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new XForm());
    }

我已经阅读了一堆SO帖子,描述了在Task.WaitAll上的锁定,但是我无法直接解释我在这里看到的现象,即 Synchronously waiting for an async operation, and why does Wait() freeze the program here

How would I run an async Task<T> method synchronously?

我确实尝试过调用task.RunSynchronously()的建议,但似乎没有任何区别。

1 个答案:

答案 0 :(得分:0)

您可以使用以下两种方法之一解决此问题。

更改为C#7.1并使主要方法为ASYNC 右键单击项目&gt;构建&gt;高级&gt; C#最新的次要版本

static async Task Main()
{
    try
    {
        using (var mgr = new UpdateManager("xxxx"))
        {
            await mgr.UpdateApp();
        }
    }
    catch (Exception ex)
    {
        logger.Debug(ex.Message);
    }

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new XForm());
}

或者

如果UpdateApp返回值

使用.Result

如果UpdateApp未返回值

使用.Wait()

static void Main()
{
    try
    {
        using (var mgr = new UpdateManager("xxxx"))
        {           
            mgr.UpdateApp().Wait();             
        }
    }
    catch (Exception ex)
    {
        logger.Debug(ex.Message);
    }

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new XForm());
}