178

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);

gturri
  • 13,807
  • 9
  • 40
  • 57
David Dury
  • 5,537
  • 12
  • 56
  • 94

5 Answers5

303

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.

bashis
  • 1,200
  • 1
  • 16
  • 35
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • 1
    For me this return type does not work (I guess I am doing something wrong). **Example** static async Task DoStuff() { ... = await SomeMethodAsync(); return "string value"; } .. var x = DoStuff(); **But this x** - is with type "Task", not with type "string"... **Why is that so?** – Prokurors Feb 09 '15 at 08:51
  • 3
    @Prokurors You need to await `DoStuff()` also. For example: `var x = await DoStuff();` – Sriram Sakthivel Feb 09 '15 at 10:04
  • 7
    Should be `return await Task.FromResult(null);` – sandeep talabathula Nov 22 '16 at 15:43
  • @sandeeptalabathula that's equal to return null – Sriram Sakthivel Nov 27 '16 at 05:51
  • A return type of `Task>` is a pretty damned rare case. Where, in practice, do normal `async` methods do this? – ProfK Jan 02 '17 at 12:44
  • 2
    @ProfK `Task.WhenAny` is an example. – Servy Mar 01 '17 at 15:34
  • "Sameway, When you return Task your method's return type should be Task>" Isn't this quite the opposite of this statement: "return 42;//Note we return int not Task and that compiles" what is it now? –  Nov 09 '17 at 14:10
  • @el_buck0 if you follow the code carefully, you'll understand that if your method is declared to return Task you just return SomeType not Task. That's what I'm trying to explain. Not sure where I contradict myself. – Sriram Sakthivel Nov 09 '17 at 14:19
  • as @sandeeptalabathula `return await Task.FromResult(null);` worked for me. – DanielV Nov 16 '18 at 09:18
78

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:

  • Task Parallel Library (TPL) simplifies adding parallelism and concurrency to applications
  • Tasks Namespace: Provides types that simplify the work of writing concurrent and asynchronous code
  • async: Use the async modifier to specify that a method, lambda expression, or anonymous method is asynchronous.
  • await operator : asynchronously await for a task to complete
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
Major
  • 5,948
  • 2
  • 45
  • 60
  • 11
    You can just return `null` directly instead of awaiting a dummy task. – Lee Aug 07 '14 at 20:36
  • 6
    @Lee, but if you do that, the compiler complains (gives a warning) that the `async` method will execute asynchronously with a suggestion to use the `await` keyword somewhere in the method. I suggest just using `return Task.FromResult((object)null);` and removing the `async` keyword to reduce the compiler warning noise. – binki Mar 25 '15 at 21:55
  • Yes, I have tried just using `return` in a Task, but the task keeps on executing, because `return` is not returning a `Task` – Turner Bass Oct 18 '18 at 18:07
36

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.

Jeremy Lakeman
  • 9,515
  • 25
  • 29
3

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";

        }))());
    }
Adel Mourad
  • 1,351
  • 16
  • 13
  • 1
    When posting code as an answer, please include some explanation of what you are demonstrating. In this case, you are adding an answer to an old question that already has several answers. Please add a sentence or two describing what your new answer is demonstrating, that wasn't already shown in the other answers. I'm not saying anything is wrong with your answer, just asking that you help others by putting into words what you are showing with your code. – ToolmakerSteve Nov 10 '19 at 12:32
0

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 ())