Как выглядит «первый» асинхронный метод? - PullRequest
0 голосов
/ 26 июня 2019

Если async метод "A" должен await для другого async метода "B", а метод "B" должен await для другого async метода "C", как метод "С" - "первый" async метод - похож? Я погуглил вопрос "Как создать метод async". Все примеры, которые я получил, похожи на ... у метода "C" есть некоторый код, такой как "Task.Run ()" внутри. Я сильно запутался. Task.Run() только для процессора, не так ли? Но метод async обычно предназначен для операций ввода-вывода. Может кто-нибудь объяснить мне это?

Ответы [ 2 ]

0 голосов
/ 27 июня 2019

Метод "С", вероятно, похож на два других.Все они помечены ключевым словом async и await другими asyhc методами внутри.Метод «C» просто ожидает собственные асинхронные методы .NET Framework вместо пользовательских.

private static async Task A()
{
    await B();
}

private static async Task B()
{
    await C();
}

private static async Task C()
{
    // Lets await a bunch of stuff just because
    await Task.Delay(1);
    await Task.Yield();
    await Task.FromResult(0).ConfigureAwait(true);
    await Task.CompletedTask.ConfigureAwait(false);
    await Task.Run(() => throw new Exception()).ContinueWith(_ => {});
}
0 голосов
/ 26 июня 2019

Многие из них обертывают ванильные асинхронные стилизованные методы, которые принимают делегат обратного вызова, который будет вызван после его завершения.

Обратите внимание, что не только Task, но и все экземпляры типов, которые соответствуют следующим правилам, могут быть await ed:

  • Должен быть метод AWAITER GetAwaiter(), вызываемый из экземпляра await ed (который также измеряет метод расширения), в то время как AWAITER представляет любые типы, соответствующие правилам.

  • AWAITER должен реализовать INotifyCompletion, чтобы принять делегата обратного вызова, который должен быть вызван в асинхронной задаче.

  • AWAITER экземпляр должен иметь bool IsCompleted { get; }, определенный для проверки его завершения.

  • AWAITER экземпляр должен иметь метод RESULT GetResult(), определенный для завершения await ing, в то время как RESULT будет типом результата выражения await, которое может быть void, если нет результата вернулся.

Например:

public static TaskAwaiter<T> GetAwaiter<T>(this T target) => Task.FromResult(target).GetAwaiter();

Этот метод позволил всем типам быть await ed, что мгновенно завершалось бы, получая само значение.

var x = await 1;  // int x = 1;

Любые типы, которые соответствуют правилам, могут быть await ed, что означает, что вы можете реализовать его самостоятельно для вызова делегата обратного вызова вручную без асинхронного метода.

Стандартный API предоставляет TaskCompletionSource<TResult> для преобразования асинхронных операций обратного вызова в Task, и вам может не потребоваться реализовать собственный ожидаемый тип, но знание того, какой синтаксис await на самом деле позволяет вам обрабатывать больше случаев.

...