Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is the return statement in async/await

I have probably worked myself into a rather immature confusion. Please refer the code below (console app)

namespace Tasks101
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            var x = p.Blah();                
        }

        private async Task Blah()
        {
            await Task.Delay(TimeSpan.FromSeconds(3)).ConfigureAwait(false);
        }

        private async void ReturnsVoid()
        {
            await Task.Delay(TimeSpan.FromSeconds(3)).ConfigureAwait(false);
        }

        private void Nothing()
        {

        }
    }
}

My question is that in Blah() method I don't have any explicit return statement yet when this executes

var x = p.Blah();

the type of x is Task. Again I have no return statement in ReturnsVoid method but that compiles too.

So the questions are

  1. What is returning a Task from the Blah method without my having a return statement there and why is that same thing not returning anything from ReturnsVoid method.
  2. How do I control what gets returned from the Blah method? What if I had two await statements there one after the other?
like image 382
Nikhil Avatar asked Aug 12 '14 15:08

Nikhil


2 Answers

The async keyword transforms the method and constructs the returned Task instance. There is nothing returned from the async void method because it returns void; this lack of a Task is one reason why you should avoid async void. async void is not a natural asynchronous method signature; it is only supported so that event handlers may be async.

If you want to return a value, then you should have the method return a Task<T>, e.g., Task<int> BlahAsync(), and then you can just return the value directly, e.g., return 13; The number of awaits in the method has nothing to do with it. When the method executes the actual return (e.g., return 13), the async keyword interprets that as completing the Task<int> that was already constructed.

I have an async intro on my blog that you may find helpful.

like image 166
Stephen Cleary Avatar answered Oct 05 '22 04:10

Stephen Cleary


  1. The compiler is generating a Task for you that represents the entire asynchronous operation.
  2. You have 3 options for async methods:
    • async void - This should be avoided in all cases other than event handlers
    • async Task - Here you have no control of the returned task, and it will be completed when the whole operation has ended (or when an exception is thrown) no matter how many awaits you have in it.
    • async Task<T> - This allows to actually return a value but behaves just the same as async Task.
like image 30
i3arnon Avatar answered Oct 05 '22 04:10

i3arnon