1

我在 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());
    }

我已经阅读了一堆描述 Task.WaitAll 锁定的 SO 帖子,但我找不到对我在这里看到的现象的直接解释,即
同步等待异步操作,以及为什么 Wait() 冻结这里的程序

我将如何同步运行异步 Task<T> 方法?

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

4

1 回答 1

0

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

更改为 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 返回一个值

使用 .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());
}
于 2018-05-08T22:49:49.167 回答