Информация об изменениях

Сообщение Re[3]: Блокирующий вызов, базовый вопрос по async\await от 19.11.2019 14:13

Изменено 19.11.2019 14:18 alexzzzz

Re[3]: Блокирующий вызов, базовый вопрос по async\await
Здравствуйте, Sharov, Вы писали:

S>Мне казалось, что суть await в данном месте это подождать в отдельном, уже созданном для ProcessTask, потоке результата операции

S>и продолжить его с кодом после await.

Как-то так оно и работает. Ты вызываешь асинхронный Test, он выполняется до первого await и возвращает управление. В результате "главный" поток печатает
1
La fin

и переходит дальше на ReadLine, где и останавливается в ожидании ввода. А то, что мы авейтим и всё остальное после него, крутится в это время в каком-то другом потоке/потоках. Поскольку приложение консольное и контекст синхронизации у главного потока не задан (его SynchronizationContext.Current is null), то вот это всё остальное после await в главный поток больше не вернётся, т.к. без контекста синхронизации не может.

static void Main(string[] args)
{
    Test();
    Console.WriteLine("La fin");
    Console.ReadLine();
}


static async void Test()
{
    while (true)
    {
        Console.WriteLine(1);
        await ProcessTaskAsync();
        Console.WriteLine(3);
    }
}
Re[3]: Блокирующий вызов, базовый вопрос по async\await
Здравствуйте, Sharov, Вы писали:

S>Мне казалось, что суть await в данном месте это подождать в отдельном, уже созданном для ProcessTask, потоке результата операции

S>и продолжить его с кодом после await.

Как-то так оно и работает. Ты вызываешь асинхронный Test, он выполняется до первого await и возвращает управление. В результате "главный" поток печатает
1
La fin

и переходит дальше на ReadLine, где и останавливается в ожидании ввода. А то, что мы авейтим и всё остальное после него, крутится в это время в каком-то другом потоке/потоках. Поскольку приложение консольное и контекст синхронизации у главного потока не задан (его SynchronizationContext.Current is null), то вот это всё остальное после await в главный поток больше не вернётся, т.к. без контекста синхронизации не может.

В WinForms/WPF-приложении результат, думаю, будет сильно другой. Там главным потокам задан SynchronizationContext.

static void Main(string[] args)
{
    Test();
    Console.WriteLine("La fin");
    Console.ReadLine();
}


static async void Test()
{
    while (true)
    {
        Console.WriteLine(1);
        await ProcessTaskAsync();
        Console.WriteLine(3);
    }
}