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>>
You essentially need to wait for the result of the task returned by
TestEmployeesGetAsync
. You can do that asyncrhonously withawait
which unwraps the result for you toList<Employee>
or you can get the result from the task with theResult
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 anasync
method requires you to do that in anotherasync
method ( as you have found out), and awaiting that method requires you to be in yet anotherasync
method, and so theasync
methods spread through the code base until you reach an event handler orMain
(which cannot be markedasync
).This proliferation of
async
methods is not unusual, and to avoid it, you can wait for the task to complete withTask.Wait
andTask.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
.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 asasync
, you can use theawait
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:
As a side note, be aware that you should not expose async wrappers over sync methods.