将任务<t>转换为T </t>

时间:2014-08-07 05:43:16

标签: c# asynchronous casting ienumerable

如何将Task<IEnumerable<IMapLocationItem>>投射到IEnumerable<IMapLocationItem>

以下是我的代码Task<IEnumerable<IMapLocationItem>>

public async Task<IEnumerable<IMapLocationItem>> GetAllMapLocationItemsFromUserName(string userName)
{
    IEnumerable<IMapLocationItem> mapLocationImageGalleries = await db.mapLocationImageGalleries.Where(m => m.userName.Equals(userName)).ToListAsync();
    IEnumerable<IMapLocationItem> mapLocationVideoGalleries = await db.mapLocationVideoGalleries.Where(m => m.userName.Equals(userName)).ToListAsync();

    IEnumerable<IMapLocationItem> mapLocationItemsCombined = mapLocationImageGalleries.Concat(mapLocationVideoGalleries);
    return mapLocationItemsCombined;
}

我可以使用关键字.Result,但我在某处读过这会阻止async任务异步,并且在使用Result关键字时此方法需要很长时间才能完成。< / p>

如何将Task<IEnumerable<IMapLocationItem>>投放到IEnumerable<IMapLocationItem>

的最佳方式

提前致谢

2 个答案:

答案 0 :(得分:9)

您无法将Task<T>投射到T,它们代表不同的东西。 Task<T>表示将来最终返回T的任务。如果您想获得任务的结果,您有几个选项(假设为t = Task<T>

  • t.Result阻止执行,直到结果可用。这有一个令人遗憾的副作用,它在某些情况下可能会死锁,最明显的是当它与UI线程中的async方法结合使用时。
  • await t计划延续并在结果可用后运行。仅适用于带有Microsoft.Bcl.Async库的C#5和.NET 4.5或.NET 4.
  • t.ContinueWith安排延续并在结果可用后运行。

一般情况下,我更喜欢使用awaitContinueWith,但有时使用Result是最简单的,特别是如果您可以访问调用方法和被调用方法的来源,因此可以确保不会发生死锁。

答案 1 :(得分:7)

来自MSDN网站http://msdn.microsoft.com/en-us/library/hh191443.aspx

 // Signature specifies Task<TResult>
 async Task<int> TaskOfTResult_MethodAsync()
 {
     int hours;
     // . . .
     // Return statement specifies an integer result.
     return hours;
 }

 // Calls to TaskOfTResult_MethodAsync
 Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync();
 int intResult = await returnedTaskTResult;
 // or, in a single statement
 int intResult = await TaskOfTResult_MethodAsync();

您无法将任务强制转换为结果。这违背了异步的目的。上面的代码是异步调用函数,然后在代码中通过调用“await”来请求结果。这将等待asnyc函数完成(将阻止代码直到完成),直到结果准备好。

问题在于,当它异步运行时,你无法预测什么时候会完成,所以我们告诉Task什么时候我们终于准备好等待结果了。它可以立即完成或在5分钟内完成。只要有必要完成该功能,Await就会等待。