Return list from async/await method
Solution 1
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());
}
Solution 2
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());
Solution 3
you can use the following
private async Task<List<string>> GetItems()
{
return await Task.FromResult(new List<string>
{
"item1", "item2", "item3"
});
}
Solution 4
Instead of doing all these, one can simply use ".Result" to get the result from a particular task.
eg: List list = GetListAsync().Result;
Which as per the definition => Gets the result value of this Task < TResult >
testing
Updated on July 09, 2022Comments
-
testing almost 2 years
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 useTask.Run
. If I remove theTask.Run(() =>
part I getCannot await System.Collections.Generic.List expression
I think I haven't fully understood the async/await methods. What I'm doing wrong?
-
Daniel Kelley over 9 yearsThey will also need to ensure that the method calling this code is made an
async
method (if they haven't already). -
testing over 9 yearsWhat I don't get is why do I have to
await
two times? -
Ben Robinson over 9 years@testing, you have to await twice because you have 2 async calls
-
testing over 9 years@BenRobinson: Do I have two async calls or only one (and the second is for "extracting")?
-
Ben Robinson over 9 years@testing You have 2, you are awaiting the task in you
GetListAsync
method, then you are awaiting the method itself in your calling code -
testing over 9 yearsI also have a try/catch block to catch the exceptions and I'm showing a spinner. So my method name is correct than?
-
NeddySpaghetti over 9 yearsyes i think it should be OK, starting a new thread is not ideal but i think the guideline is more about calling a synchronous version of the function inside
Task.Run