简体   繁体   中英

What does “the first” async method look like?

If an async method "A" has to await on another async method "B", and the method "B" has to await on another async method "C", how does the method "C" - "the first" async method - look like? I googled the question "How to create an async method". All the examples I got is like...the method "C" has some code like "Task.Run()" inside. I am badly confused. Task.Run() is for CPU-bound only, isn't it? But async method is usually for I/O bound operations. Can someone please explain this to me?

Many of them are wrapping the vanilla asynchronous styled methods that take callback delegate which will be called when it is completed.

Note that not only Task but also all instances of types that match the following rules could be await ed:

  • There must be a AWAITER GetAwaiter() method callable from the await ed instance (which meas an extension method is also accepted), while the AWAITER represents any types that match the rules.

  • AWAITER must implement INotifyCompletion to accept a callback delegate that should be called on the asynchronous task is completed.

  • AWAITER instance must have a bool IsCompleted { get; } bool IsCompleted { get; } defined to check if it is completed.

  • AWAITER instance must have a RESULT GetResult() method defined to finish await ing, while RESULT would be the result type of the await expression which could be void if no result is returned.

For example:

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

This method enabled all types to be await ed, that would complete instantly resulting the value itself.

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

Any types that match the rules could be await ed, which means you can implement it by yourself to invoke the callback delegate manually without an asynchronous method.

The standard API provides TaskCompletionSource<TResult> for wrapping callback asynchronous operations to Task , and you may not need to implement your own awaitable type, but knowing what await syntax actually does enable you to handle more cases.

The "C" method probably look like the other two. All are marked with the async keyword, and await other asyhc methods internally. The "C" method just awaits native async methods of the .NET Framework, instead of custom ones.

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(_ => {});
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM