I am trying to understand the usage of async await and i studied few blog posts and now i have made a testing code but it is not working the way i am expecting it to work.
I have a method which returns List:
private List<Employee> GetEmployees()
{
IList<Employee> list = new List<Employee>();
list.Add(new Employee() { Id = 1, Age = 20, Name = "Kavin" });
list.Add(new Employee() { Id = 2, Age = 30, Name = "Alen" });
list.Add(new Employee() { Id = 3, Age = 20, Name = "Suresh" });
list.Add(new Employee() { Id = 4, Age = 30, Name = "Jay" });
list.Add(new Employee() { Id = 5, Age = 20, Name = "Nanda" });
list.Add(new Employee() { Id = 5, Age = 20, Name = "Kavin" });
list.Add(new Employee() { Id = 5, Age = 20, Name = "Kavin" });
list.Add(new Employee() { Id = 1, Age = 23, Name = "Test" });
return list;
}
Then i wrote my async method:
private async Task<List<Employee>> TestEmployeesGetAsync()
{
var result = await Task.Run(() => GetEmployees());
return result;
}
When i call this method :
var Result = TestEmployeesGetAsync();
The visual studio is telling me that it returns Task<List<T>>
and it usage is:
List<Employee> result = await TestEmployeesGetAsync();
Why i need to put await on the calling method if i put await
it gives compiler error of course because await
should have async as well. Can somebody clear my mind how to call it so that i can get List<T>
instead of Task<List<T>>
For methods other than event handlers that don't return a value, you should return a Task instead, because an async method that returns void can't be awaited. Any caller of such a method must continue to completion without waiting for the called async method to finish.
The behavior of async / await is similar to combining generators and promises. Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.
Why i need to put await on the calling method if i put await it gives compiler error of course because await should have async as well.
There are a few dependencies the compiler needs in order to understand you're running an async method. The signal is the async
modifier on the method declaration. Once you mark it as async
, you can use the await
keyword. That is why async propagates "all the way" down the call stack, as when you call one async method and need to await its result, you'll need to mark the consuming method with the async modifier.
In order to make your method work, you'll need to do the following:
public async Task GetEmployeesAsync()
{
List<Employees> result = await TestEmployeesGetAsync();
}
As a side note, be aware that you should not expose async wrappers over sync methods.
You essentially need to wait for the result of the task returned by TestEmployeesGetAsync
. You can do that asyncrhonously with await
which unwraps the result for you to List<Employee>
or you can get the result from the task with the Result
property. However that can cause a deadlock so you need to be careful.
With async-await
it tends to make its way up the call chain, i.e. awaiting an async
method requires you to do that in another async
method ( as you have found out), and awaiting that method requires you to be in yet another async
method, and so the async
methods spread through the code base until you reach an event handler or Main
(which cannot be marked async
).
This proliferation of async
methods is not unusual, and to avoid it, you can wait for the task to complete with Task.Wait
and Task.Result
but these are blocking method and can cause the aforementioned deadlock. It is also an anti-pattern called sync over async and it defeats the purpose of doing the work asynchronously as you'll end up blocking waiting for it to finish anyway.
As pointed out by @BenVoigt, one exception is when you kick off multiple asynchronous requests and then block waiting for all the tasks to complete with Task.WaitAll
.
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