从 async/await 方法返回列表
Posted
技术标签:
【中文标题】从 async/await 方法返回列表【英文标题】:Return list from async/await method 【发布时间】:2014-11-01 11:29:51 【问题描述】:我想使 web 服务请求异步。我在这里称呼它:
List<Item> list = GetListAsync();
这是我的函数的声明,它应该返回一个列表:
private async Task<List<Item>> GetListAsync()
List<Item> list = await Task.Run(() => manager.GetList());
return list;
如果我想编译我得到以下错误
Cannot implicitely convert type System.Threading.Tasks.Task<System.Collections.Generic.List<Item>> to System.Collections.Generic.List<Item>
据我所知,如果我使用 async
修饰符,结果会自动用 Task 包装。我认为这不会发生,因为我使用Task.Run
。如果我删除 Task.Run(() =>
部分,我会得到
无法等待 System.Collections.Generic.List 表达式
我想我还没有完全理解 async/await 方法。我做错了什么?
【问题讨论】:
Cannot implicitly convert type from Task<>的可能重复 【参考方案1】:您需要更正代码以等待下载列表:
List<Item> list = await GetListAsync();
另外,请确保此代码所在的方法具有async
修饰符。
您收到此错误的原因是GetListAsync
方法返回了一个Task<T>
,它不是一个完整的结果。由于您的列表是异步下载的(因为Task.Run()
),您需要使用await
关键字从任务中“提取”值。
如果您删除Task.Run()
,您的列表将被同步下载,您不需要使用Task
、async
或await
。
还有一个建议:如果您只是将操作委托给不同的线程,则无需在 GetListAsync
方法中等待,因此您可以将代码缩短为以下内容:
private Task<List<Item>> GetListAsync()
return Task.Run(() => manager.GetList());
【讨论】:
他们还需要确保调用此代码的方法是async
方法(如果他们还没有的话)。
我不明白为什么我必须await
两次?
@testing,你必须等待两次,因为你有 2 个异步调用
@BenRobinson:我有两个异步调用还是只有一个(第二个用于“提取”)?
@testing 你有 2 个,你在 GetListAsync
方法中等待任务,然后你在调用代码中等待方法本身【参考方案2】:
除了@takemyoxygen 的回答之外,函数名称以Async
结尾的约定是该函数是真正异步的。 IE。它不会启动新线程,也不会简单地调用Task.Run
。如果这是您函数中的所有代码,最好将其完全删除并简单地拥有:
List<Item> list = await Task.Run(() => manager.GetList());
【讨论】:
我还有一个 try/catch 块来捕获异常,我正在展示一个微调器。所以我的方法名比正确吗? 是的,我认为应该没问题,开始一个新线程并不理想,但我认为该指南更多的是关于在Task.Run
中调用函数的同步版本【参考方案3】:
为我工作:
List<Item> list = Task.Run(() => manager.GetList()).Result;
这样就不需要在调用中用异步标记方法了。
【讨论】:
它可以工作,但对我来说仍然是同步运行的。【参考方案4】:你可以使用下面的
private async Task<List<string>> GetItems()
return await Task.FromResult(new List<string>
"item1", "item2", "item3"
);
【讨论】:
【参考方案5】:您可以简单地使用“.Result”来获取特定任务的结果,而不是执行所有这些操作。
例如: 列表列表 = GetListAsync().Result;
按照定义 => 获取这个Task的结果值
【讨论】:
以上是关于从 async/await 方法返回列表的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 async/await 的 mongoose 承诺