Асинхронное поведение в ожидании консольного приложения и WPF - PullRequest
0 голосов
/ 27 февраля 2019

Я новичок в асинхронном ожидании.Я думаю, что я понял пример консольного приложения.При передаче идентичного кода в WPF возникает тупик, и я не знаю точно, почему.

// All as expected
// Output:
// LongOperationAsync Start
// Before task.Wait();
// LongOperationAsync End
// After task.Wait();
// Result: 4711

class Program {
    public static void Main() {
        Task<int> task = LongOperationAsync();
        //Console.ReadKey();
        Console.WriteLine("Before task.Wait();");
        task.Wait();
        Console.WriteLine("After task.Wait();");
        var result = task.Result;
        Console.WriteLine("Result: {0}", result);
        Console.ReadKey();
    }

    static async Task<int> LongOperationAsync() {
        Console.WriteLine("LongOperationAsync Start");
        await Task.Delay(1000);
        Console.WriteLine("LongOperationAsync End");
        return 4711;
    }
}

, а вот код блокировки WPF:

// WPF handler Output:
// LongOperationAsync Start
// Before task.Wait(); => Blocking

private void button2_Click(object sender, EventArgs e) {
    Task<int> task = LongOperationAsync();
    Debug.WriteLine("Before task.Wait();");
    task.Wait();
    Debug.WriteLine("After task.Wait();");
    var result = task.Result;
    Debug.WriteLine("Result: {0}", result);
}

private async Task<int> LongOperationAsync() {
    Debug.WriteLine("LongOperationAsync Start");
    await Task.Delay(1000);
    Debug.WriteLine("LongOperationAsync End");
    return 4711;
}

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

В вашем примере вы можете изменить нажатие кнопки для асинхронного.Ваша задача блокируется, потому что вы никогда не запускаете его, вы никогда не сможете передать вызов "wait ()", не запустив задачу.

Ниже модифицированного метода нажатия кнопки.

private async void button2_Click(object sender, EventArgs e)
{
    var result = await LongOperationAsync();
    Debug.WriteLine("Result: {0}", result);
}
0 голосов
/ 27 февраля 2019

Кодовые блоки в обоих случаях.Оба примера плохие.Ни один из них не выполняется асинхронно.

Код консоли правильный будет:

public static async Task Main()
{
    Console.WriteLine("Before LongOperationAsync");

    int result = await LongOperationAsync();

    Console.WriteLine("After LongOperationAsync");
    Console.WriteLine("Result: {0}", result);
    Console.ReadKey();
}

Эквивалентный код WPF будет:

private async void button2_Click(object sender, EventArgs e)
{
    Debug.WriteLine("Before LongOperationAsync");

    int result = await LongOperationAsync();

    Debug.WriteLine("After LongOperationAsync");
    Debug.WriteLine("Result: {0}", result);
}

async является синтаксическим сахаром, который позволяет использовать ключевое слово await.await ожидает в асинхронном режиме для выполнения уже асинхронной операции, такой как Task.Delay(), без блокировки исходного потока.Когда эта асинхронная операция завершается, await возобновляет выполнение в исходном контексте синхронизации.В случае приложения WPF это поток пользовательского интерфейса.Это то, что позволяет обновлять пользовательский интерфейс после await.

async void только для обработчиков событий, таких как button2_click.Во всех остальных случаях следует использовать async Task.async void методов нельзя ожидать, и приложение не может знать, завершены они или нет.

...