Требуется ли asyn c лямбда при передаче функции, ожидающей Fun c ? - PullRequest
0 голосов
/ 30 марта 2020

У меня есть метод executor:

public static async Task<T> ExecuteAsync(Func<Task<T>> method)
{
    await method();
}

При вызове его оба

await ExecuteAsync( () => obj.MethodAsync());

и

await ExecuteAsync( async () => await obj.MethodAsync());

, кажется, работают нормально и окончательно sh примерно в то же время, порождая примерно такое же количество потоков. Насколько я понимаю, в первом случае метод будет выполняться синхронно внутри лямбды, а лямбда будет выполняться асинхронно, а во втором примере и метод, и лямбда будут выполняться асинхронно.

1 Ответ

2 голосов
/ 30 марта 2020

async и await применяются только к определениям метода.

async означает, что компилятор сгенерирует конечный автомат для метода.

await означает, что Компилятор сгенерирует код для синхронного ожидания завершения метода invoke.

ExecuteAsync(() => obj.MethodAsync())

переводит что-то в:

[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
    public C<T> obj;

    internal Task<T> <M>b__0()
    {
        return obj.MethodAsync();
    }
}

// ...

<>c__DisplayClass0_0 <>c__DisplayClass0_ = new <>c__DisplayClass0_0();
<>c__DisplayClass0_.obj = obj;
ExecuteAsync(new Func<Task<T>>(<>c__DisplayClass0_.<M>b__0));

С другой стороны,

ExecuteAsync( async () => await obj.MethodAsync())

переводится во что-то более сложное с использованием вложенных конечных автоматов.

Попробуйте sharplab.io , чтобы увидеть уменьшенный код.

На самом деле самая простая версия будет выглядеть так:

await ExecuteAsync(obj.MethodAsync);
...