Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use async and await with Task<>?

Tags:

c#

async-await

If I have a normal method that I want to make asynchronous:

public int Foo(){}

I would do:

public Task<int> FooAsync(){
    return Task.Run(() => Foo());
}

Why would I do:

public async Task<int> FooAsync(){
    return await Task.Run(() => Foo());
}

The way I plan to use this is:

FooAsync().ContinueWith((res) => {});

I want the method to just run without stopping, but I want something like a callback to be fired, hence the ContinueWith. But with the second version, is there a point to using it?

like image 465
Shawn Mclean Avatar asked Sep 03 '12 03:09

Shawn Mclean


2 Answers

In my understanding, you only need async and await when you write a method which does some async calls inside, but you would like it to look like it doesn't. In other words you want to write and read code as if it was some normal sequential code, handle exceptions as if it was normal sequential code, return values as if it was normal sequential code and so on. Then compiler's responsibility is to rewrite that code with all the necessary callbacks preserving the logic.

Your method is so simple I don't think it needs that rewriting at all, you can just return the task, but whoever consumes it may want to await for its return value.

like image 184
Max Galkin Avatar answered Oct 21 '22 07:10

Max Galkin


Why would I do:

 public async Task<int> FooAsync()
 {
  return await Task.Run(() => Foo());
 }

You wouldn't. Your previous version returns Task which is already awaitable. This new version doesn't add anything.

The way I plan to use this is:

  FooAsync().ContinueWith((res) => {});

I want the method to just run without stopping, but I want something like a callback to be fired, hence the ContinueWith.

This is where the difference comes in. Let's flesh out your example a little bit:

void DoAsyncStuff()
{
    FooAsync().ContinueWith((res) => { DoSomethingWithInt(res.Result) });
}

Using async, you can write the same code like this:

void async DoAsyncStuff()
{
    int res = await FooAsync();
    DoSomethingWithInt(res);
}

The result is the same. The await keyword turns the rest of your method into a continuation which gets resumed after FooAsync produces a value. It's just like your other code, but easier to read. *shrug*

like image 41
Mud Avatar answered Oct 21 '22 06:10

Mud