Return list from async/await method

testing picture testing · Sep 8, 2014 · Viewed 101.2k times · Source

I want to make a webservice request asynchron. I call it here:

List<Item> list = GetListAsync();

Here is the declaration of my function, which should return a list:

private async Task<List<Item>> GetListAsync(){
    List<Item> list = await Task.Run(() => manager.GetList());
    return list;
}

If I want to compile I get the following error

Cannot implicitely convert type System.Threading.Tasks.Task<System.Collections.Generic.List<Item>> to System.Collections.Generic.List<Item>

As I know If I use the async modifier the result is automatically wrapped with Task. I think this doesn't happen because I use Task.Run. If I remove the Task.Run(() => part I get

Cannot await System.Collections.Generic.List expression

I think I haven't fully understood the async/await methods. What I'm doing wrong?

Answer

takemyoxygen picture takemyoxygen · Sep 8, 2014

You need to correct your code to wait for the list to be downloaded:

List<Item> list = await GetListAsync();

Also, make sure that the method, where this code is located, has async modifier.

The reason why you get this error is that GetListAsync method returns a Task<T> which is not a completed result. As your list is downloaded asynchronously (because of Task.Run()) you need to "extract" the value from the task using the await keyword.

If you remove Task.Run(), you list will be downloaded synchronously and you don't need to use Task, async or await.

One more suggestion: you don't need to await in GetListAsync method if the only thing you do is just delegating the operation to a different thread, so you can shorten your code to the following:

private Task<List<Item>> GetListAsync(){
    return Task.Run(() => manager.GetList());
}