Почему Task.WaitAll зависает, когда форма запускается непосредственно в Main ()? - PullRequest
0 голосов
/ 09 мая 2018

Я добавил форму заставки в приложение C # WinForms для отображения во время инициализации приложения / проверки обновлений. Я использую Squirrel.Windows для проверки обновлений в Program.cs.

После добавления заставки, вызов Task.WaitAll в Main () никогда не возвращается. Этот вызов работал, как я и ожидал, до добавления заставки.

Что я могу сделать, чтобы задача завершилась в 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, но я не могу найти прямого объяснения явлений, которые я здесь вижу, т.е.
Синхронно ожидает асинхронную операцию и почему Wait () останавливает программу здесь

Как запустить синхронный метод асинхронной задачи ?

Я попытался предложить вызов task.RunSynchronously (), но, похоже, это не имело значения.

1 Ответ

0 голосов
/ 09 мая 2018

Вы можете решить эту проблему, используя один из двух подходов.

Перейдите на C # 7.1 и сделайте ваш основной метод ASYNC Щелкните правой кнопкой мыши проект> Build> Advanced> 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 возвращает значение

использовать .Результат

Если 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());
}
...