Reputation: 9839
I have following code,
using System;
using System.Threading.Tasks;
namespace asyncawait
{
class Practice
{
async Task<int> Method()
{
for (int i = 0; i < int.MaxValue ; i++);
return 10;
}
public async void caller()
{
int a = await Method();
Console.WriteLine("Please print it first");
Console.WriteLine(a);
Console.WriteLine("Please print it last");
}
}
class Program
{
static void Main(string[] args)
{
Practice p = new Practice();
p.caller();
}
}
}
Warning While Building Project:
Program.cs(9,25,9,31): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
My expectation was,
Expected Output: (First line should get immediately printed)
Please print it first // no wait because I am not using
a
and function is await
10
Please print it last
Actual Output:
Please print it first // waiting to execute function then prints output
10
Please print it last
I do not understand, why my function is taking time
cannot work asynchronous? I am really not able to understand concept after looking at lot many examples.
Upvotes: 0
Views: 1640
Reputation:
When you use the await
keyword, you are telling the current method to wait for the result of the Task
you pass to it. The magic comes from the fact that while waiting, the method is suspended and the calling thread can go on with other work.
When you put await Method()
as your first statement, the rest of the function is executed only after the result of Method()
is available, regardless of what is happening outside the function in between. To achieve the behavior you want, you should fire the task first, then print the first line, and then wait for the result. That is:
public async void caller() {
var a = Method(); // <- The task is running now asynchronously
Console.WriteLine("Please print it first"); // <- The line is printed.
Console.WriteLine(await a); // <- the result of a is waited for and printed when available.
Console.WriteLine("Please print it last");
}
Also note that the Method
is not executed asynchronously just because of the async
keyword. To create a asynchronous method, you should return a Task
, for example:
Task<int> Method() {
return Task.Run( () => {
// ... the previous function body...
});
}
Upvotes: 1
Reputation: 127603
all the async
keyword does is allow you to use the await
keyword inside a function. If you don't call await
the function behaves the same as if you did not do any async
keyword at all.
Take a look at this image from the msdn page "Asynchronous Programming with Async and Await (C# and Visual Basic)"
If you follow the black line all that happens on the same thread, unbroken until you get to 6
. Then at that point the function returns and continues later when the results are ready. Because you don't have a await
in your code your "black line" goes through your entire function.
To make it work like you want to you need to signal in the function where it should go back to the caller.
async Task<int> Method()
{
for (int i = 0; i < int.MaxValue ; i++)
{
await Task.Yield(); //Your function now returns to the caller at this point then comes back later to finish it. (Your program will be much slower now because it is going to wait int.MaxValue times.)
}
return 10;
}
Upvotes: 7
Reputation: 1515
Try to replace code of your Main() method with following:
Task.Run(
() =>
{
Practice p = new Practice();
p.caller();
});
You will get your answer.
Upvotes: 0