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

Why does Task.WaitAll hang when a form is launched directly in Main()?

我已经向 C# WinForms 应用程序添加了启动屏幕表单,以便在应用程序 initialized/checking 进行更新时显示。我正在使用 Squirrel.Windows 检查 Program.cs 中的更新。

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

当启动画面显示在前台时,我可以做些什么来确保任务在 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());
    }

我读过很多描述 Task.WaitAll 锁定的 SO 帖子,但我找不到对我在这里看到的现象的直接解释,即
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() 的建议,但似乎没有任何区别。

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

更改为 C# 7.1 并将您的主要方法设为 ASYNC 右键单击项目 > 构建 > 高级 > 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 return 是一个值

使用.Result

如果 UpdateApp 没有return一个值

使用 .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());
}