testing
testing

Reputation: 20279

Return list from async/await method

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?

Upvotes: 53

Views: 201435

Answers (5)

avinava basu
avinava basu

Reputation: 147

Instead of doing all these, one can simply use ".Result" to get the result from a particular task, e.g.:

List<Item> list = GetListAsync().Result;

Which as per the definition => Gets the result value of this Task <TResult>

Upvotes: 3

Lloyd
Lloyd

Reputation: 277

you can use the following

private async Task<List<string>> GetItems()
{
    return await Task.FromResult(new List<string> 
    { 
      "item1", "item2", "item3" 
    });
}

Upvotes: 9

user5683877
user5683877

Reputation:

Works for me:

List<Item> list = Task.Run(() => manager.GetList()).Result;

in this way it is not necessary to mark the method with async in the call.

Upvotes: 9

NeddySpaghetti
NeddySpaghetti

Reputation: 13495

In addition to @takemyoxygen's answer the convention of having a function name that ends in Async is that this function is truly asynchronous. I.e. it does not start a new thread and it doesn't simply call Task.Run. If that is all the code that is in your function, it will be better to remove it completely and simply have:

List<Item> list = await Task.Run(() => manager.GetList());

Upvotes: 13

takemyoxygen
takemyoxygen

Reputation: 4394

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());
}

Upvotes: 96

Related Questions