I cannot find any information on the actually difference.
So I have always done the following:
public async Task<int> DoSomethingAsync()
{
DoSomethingElse()
var result = await GetValueAsync();
var intValue = DoAnotherThing(result);
return intValue;
}
await
the call and then use it straight after, but I have seen recently a few posts where people are doing the following:
public async Task<int> DoSomethingAsync()
{
var task = GetValueAsync();
DoSomethingElse()
var result = await task;
var intValue = DoAnotherThing(result);
return intValue;
}
So does this mean that the method GetValueAsync
is starting it's execution and then we await the result of it later? Or does it mean that it's executing synchronously but it's still await
able?
Async methods are intended to be non-blocking operations. An await expression in an async method doesn't block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method.
An async keyword is a method that performs asynchronous tasks such as fetching data from a database, reading a file, etc, they can be marked as “async”. Whereas await keyword making “await” to a statement means suspending the execution of the async method it is residing in until the asynchronous task completes.
Async/Await is used to work with promises in asynchronous functions. It is basically syntactic sugar for promises. It is just a wrapper to restyle code and make promises easier to read and use. It makes asynchronous code look more like synchronous/procedural code, which is easier to understand.
async and awaitInside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
Damien_The_Unbeliever is right when he said that it depends on the implementation.
class Program
{
public static int DoAnotherThing(string value)
{
return int.Parse(value);
}
public static async Task<string> GetValueAsync()
{
await Task.Delay(5000);
return "12";
}
public static void DoSomethingElse()
{
Thread.Sleep(5000);
}
public static async Task<int> DoSomethingAsyncA()
{
DoSomethingElse();
var result = await GetValueAsync();
var intValue = DoAnotherThing(result);
return intValue;
}
public static async Task<int> DoSomethingAsyncB()
{
var task = GetValueAsync();
DoSomethingElse();
var result = await task;
var intValue = DoAnotherThing(result);
return intValue;
}
public static void Measure(Action act)
{
var sw = new Stopwatch();
sw.Start();
act();
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
static void Main(string[] args)
{
Measure(() => DoSomethingAsyncA().Wait());
Measure(() => DoSomethingAsyncB().Wait());
Console.ReadLine();
}
}
In this case DoSomethingAsyncB
will take ~5 seconds, where DoSomethingAsyncA
will take ~10. However if your GetValueAsync
returns a value computation of which was started somewhere else, then there will be no difference.
UPDATE I corrected the mistake in the answer. And here is the output from my machine:
00:00:10:0161446
00:00:05:0032000
In this
public async Task<int> DoSomethingAsync()
{
DoSomethingElse()
var result = await GetValueAsync();
var intValue = DoAnotherThing(result);
return intValue;
}
It means that when you await the GetValueAsync's result as soon as possible without executing any other code.
The code below means :
public async Task<int> DoSomethingAsync()
{
var task = GetValueAsync();
DoSomethingElse()
var result = await task;
var intValue = DoAnotherThing(result);
return intValue;
}
You call GetValueAsync and do DoSomethingElse while waiting GetValueAsync to finish it and then when it is finished it continues executing DoAnotherThing
Quite often people think that async-await is done by several threads. Usually this isn't not the case. Unless you start other threads, all code is performed by the same thread. Checking the ThreadId of the current thread will show you this.
In an interview Eric Lippert explained async-await in a restaurant metaphor. Search somewhere in the middle for async await.
He explains that if a cook toasts some bread he can wait until the bread is toasted or start doing something else and come back later to see if the toaster finished toasting.
The same happens in your second DoSomethingAsync. When writing date to a disk, your thread delivers the data to the disk writer. Writing to disks is a relatively slow process. The thread doesn't wait for the date to be written, instead it starts doing something else. When it finished doing something else, the thread awaits until the disk write has finished writing to disk.
This is only useful if the disk write can continue writing while your thread is doing something else. Therefore you usually see async functions when hardware is involved, or processes that start other threads to do some work. If the async function has to do some time consuming calculations it is not useful to make the function async, unless it starts another thread to do the calculations. Even then it is questionable whether this should be done inside an async function or whether the caller should have the freedom to decide whether to let his own thread do the calculations or start a different thread to do this.
Another article that helped me to understand async-await by Stephen Cleary, a great contributor to this site (thanks again Stephen!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With