Return list from async/await method

136,787

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 >

Share:
136,787
testing
Author by

testing

Updated on July 09, 2022

Comments

  • testing
    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 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?

  • Daniel Kelley
    Daniel Kelley over 9 years
    They will also need to ensure that the method calling this code is made an async method (if they haven't already).
  • testing
    testing over 9 years
    What I don't get is why do I have to await two times?
  • Ben Robinson
    Ben Robinson over 9 years
    @testing, you have to await twice because you have 2 async calls
  • testing
    testing over 9 years
    @BenRobinson: Do I have two async calls or only one (and the second is for "extracting")?
  • Ben Robinson
    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
    testing over 9 years
    I also have a try/catch block to catch the exceptions and I'm showing a spinner. So my method name is correct than?
  • NeddySpaghetti
    NeddySpaghetti over 9 years
    yes 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