Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async await returning Task<List<T>> instead of List<T> on calling aync method

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>>

like image 369
Ehsan Sajjad Avatar asked Dec 05 '14 05:12

Ehsan Sajjad


People also ask

Why does async return task?

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.

What is the return type of async await?

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.


2 Answers

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.

like image 147
Yuval Itzchakov Avatar answered Oct 11 '22 02:10

Yuval Itzchakov


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.

like image 45
NeddySpaghetti Avatar answered Oct 11 '22 01:10

NeddySpaghetti