将任务<T>转换为T

use*_*648 7 c# ienumerable asynchronous casting

我怎么投的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;
}
Run Code Online (Sandbox Code Playgroud)

我可以使用关键字.Result,但我已经读过这个地方,这可以防止async任务异步,并且这个方法在使用Result关键字时需要很长时间才能完成.

如何投射Task<IEnumerable<IMapLocationItem>>到最佳方式IEnumerable<IMapLocationItem>

提前致谢

Dir*_*irk 10

你可以不投一Task<T>T,他们代表不同的东西.A Task<T>表示将来最终会返回的任务T.如果你想获得任务的结果,你有几个选择(假设t = Task<T>)

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

一般来说,我更喜欢使用awaitor ContinueWith,但有时使用Result是最简单的,特别是如果你有权访问调用和被调用方法的源,从而可以确保不会发生死锁.


Ser*_*rov 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();
Run Code Online (Sandbox Code Playgroud)

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

问题在于,当异步运行时,您无法预测何时会完成某些操作,因此我们告诉Task我们何时最终准备好等待结果.它可以立即完成或在5分钟内完成.只要有必要完成该功能,Await将等待.