консольное приложение и пример ожидания асинхронной блокировки - PullRequest
0 голосов
/ 01 марта 2019

Почему блокируется следующий пример?Я ожидал, что «Run First» запустится немедленно, а через 5 секунд появится «Run Last».

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            // Call SomeAsyncCode() somehow
            SomeAsyncCode().GetAwaiter().GetResult();

            Console.WriteLine("Run First");
        }

        private static async Task SomeAsyncCode()
        {
            // Use await here!
            await Task.Delay(5000);

            Console.WriteLine("Run Last");
            // Other async goodness...
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Когда вы определяете async Task Method() - вы говорите, что этот метод следует ожидать, даже если он ничего не даст.

Когда вы определяете async void Method() - вы говорите, что это fire 'n'forget метод, и вы не хотите его ждать.

Кроме того, когда вы void Main(string[] args) возвращаетесь - ваше приложение закрывается и GC убьет все ваши задачи.

Итак, ваш код должен быть примерно таким:

static void Main(string[] args)
{
    // Call SomeAsyncCode() somehow
    SomeAsyncCode();

    Console.WriteLine("Run First");
    Console.ReadKey(); // you need this to prevent app from closing
}

private static async void SomeAsyncCode()
{
    // Use await here!
    await Task.Delay(5000);

    Console.WriteLine("Run Last");
    // Other async goodness...
}
0 голосов
/ 01 марта 2019

Вы ожидаете (термин используется свободно) задачи.

Было бы больше смысла, если бы вы не использовали .GetAwaiter().GetResult(); (которые в любом случае являются внутренними методами фреймворка) и просто написали

SomeAsyncCode().Wait();
Console.WriteLine("Run First");

Тогда становится очевидным, что происходит, вы ждетедля выполнения задачи.

Следующее, вероятно, больше похоже на то, что вы ожидаете;

// start task
var task = SomeAsyncCode();

Console.WriteLine("Run First");

task.Wait();

Хотя, честно говоря, редко нужно звонить, Wait, Result или GetAwaiter().GetResult() в методе async, при этом в приложении UI или в чем-либо с контекстом синхронизации , скорее всего, возникнет тупик

В идеалевы позволяете async и await распространяться, в C # 7.1 и выше у вас есть возможность создать async Entry Point , которая позволяет вам использовать Async иОжидать шаблон более кратким образом

static async Task Main(string[] args)
{
    await SomeAsyncCode();
    Console.WriteLine("Run First");
}

или

static async Task Main(string[] args)
{     
    var task = SomeAsyncCode();
    Console.WriteLine("Run First");
    await Task.WhenAll(task);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...