154
votes

Can somebody explain what does this means into a synchronous method? If I try to change the method to async then VS complain about it.

This works:

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

This doesn't work:

public async Task MethodName()
{
     return Task.FromResult<object>(null);
}

So basically I would like to know what exactly this means: Task.FromResult<object>(null);

5
@L.B hmm that works! But also if i just return; works also ... !David Dury
"doesn't work" does not provide a very good description of what is not working. What is the error message you receive?John Koerner
@JohnKoerner I think it’s pretty obvious that the compiler might give you the same error as if you tried to return a value in a void function.binki

5 Answers

265
votes

async methods are different than normal methods. Whatever you return from async methods are wrapped in a Task.

If you return no value(void) it will be wrapped in Task, If you return int it will be wrapped in Task<int> and so on.

If your async method needs to return int you'd mark the return type of the method as Task<int> and you'll return plain int not the Task<int>. Compiler will convert the int to Task<int> for you.

private async Task<int> MethodName()
{
    await SomethingAsync();
    return 42;//Note we return int not Task<int> and that compiles
}

Sameway, When you return Task<object> your method's return type should be Task<Task<object>>

public async Task<Task<object>> MethodName()
{
     return Task.FromResult<object>(null);//This will compile
}

Since your method is returning Task, it shouldn't return any value. Otherwise it won't compile.

public async Task MethodName()
{
     return;//This should work but return is redundant and also method is useless.
}

Keep in mind that async method without an await statement is not async.

64
votes

You need to use the await keyword when use async and your function return type should be generic Here is an example with return value:

public async Task<object> MethodName()
{
    return await Task.FromResult<object>(null);
}

Here is an example with no return value:

public async Task MethodName()
{
    await Task.CompletedTask;
}

Read these:

TPL: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx and Tasks: http://msdn.microsoft.com/en-us/library/system.threading.tasks(v=vs.110).aspx

Async: http://msdn.microsoft.com/en-us/library/hh156513.aspx Await: http://msdn.microsoft.com/en-us/library/hh156528.aspx

33
votes

Adding the async keyword is just syntactic sugar to simplify the creation of a state machine. In essence, the compiler takes your code;

public async Task MethodName()
{
     return null;
}

And turns it into;

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

If your code has any await keywords, the compiler must take your method and turn it into a class to represent the state machine required to execute it. At each await keyword, the state of variables and the stack will be preserved in the fields of the class, the class will add itself as a completion hook to the task you are waiting on, then return.

When that task completes, your task will be executed again. So some extra code is added to the top of the method to restore the state of variables and jump into the next slab of your code.

See What does async & await generate? for a gory example.

This process has a lot in common with the way the compiler handles iterator methods with yield statements.

3
votes

This is a Task that is returning a Task of type String (C# anonymous function or in other word a delegation is used 'Func')

    public static async Task<string> MyTask()
    {
        //C# anonymous AsyncTask
        return await Task.FromResult<string>(((Func<string>)(() =>
        {
            // your code here
            return  "string result here";

        }))());
    }
0
votes

In order to get proper responses back from async methods, you need to put await while calling those task methods. That will wait for converting it back to the returned value type rather task type.

E.g var content = await StringAsyncTask (

where public async Task<String> StringAsyncTask ())