2016-08-20 56 views
0

我设立一个Task[]阵列,所以我可以用Task.WhenAll()这样的:如何解开任务<IEnumerable>以处理结果?

Task[] tasks = new Task[2]; 

     tasks[0] = _widgetDataService.RetrieveAsync<CollaboratorNetworkNode>(
      "get_collaborator_nodes", portfolio, 
      recentFys, nodesSwitch); 

     tasks[1] = _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>(
      "get_collaborator_edges", portfolio, recentFys); 

     await Task.WhenAll(); 

的代码运行正常,并在Task.WhenAll到达一个破发点。

但现在我去跑这个代码:

var nodes = from pi in (IEnumerable<CollaboratorNetworkNode>)tasks[0] 
        select new GraphNode { Id = pi.ProfileId, Properties = pi, Labels = new[] { "Person" } }; 

,我得到的错误信息:

无法转换 类型的对象System.Threading.Tasks.Task'1 [System.Collections.Generic.IEnumerable'1 [Nete.Ireport.Models.ViewModels.CollaboratorNetworkNode]]' to type 'System.Collections.Generic.IEnumerable'1 [Nete.Ireport.Models.ViewModels.CollaboratorNetworkNode]'。

如果我尝试只运行这个命令:

var nodes = from pi in tasks[0] 
        select new GraphNode { Id = pi.ProfileId, Properties = pi, Labels = new[] { "Person" } }; 

我不能编译,因为我得到的红色波浪有:

任务不包含选择的定义和最佳推广 方法超载“DynamicQueryable.Select(IQueryable,string,params object [] require IQueryable type。

我们只是试图运行这两个检索服务,每个都是10秒。所以我们的电话是20秒。 我现在正在13到15秒内到达转折点。 所以,如果我能得到这个工作,我已经削掉5到7秒。

但我不知道如何使用结果。

我该如何完成这个方法?

+2

您需要使用Task.Result。如果你将自己的任务视为一个普通的“任务”(而不是“任务”),那么你需要首先投入才能访问'.Result.' –

+2

'等待Task.WhenAll() ;'这是不会做任何事情...... –

+0

格洛林 - 你能再详细一点吗? – Sam

回答

1

您需要的任务阵列传递给WhenAll方法:

await Task.WhenAll(tasks); 

然后你就可以使用存储的结果Result物业:

var result1 = (Task[0] as Task<IEnumerable<CollaboratorNetworkNode>>).Result; 
var result2 = (Task[1] as Task<IEnumerable<CollaboratorNetworkEdge>>).Result; 

更改以上任何的回报您异步调用的方法的类型。

注意:使用Task.Result非常仔细,如果Task尚未完成。

+0

非常感谢。就是这样。 你刚刚帮我刮了6秒这个方法。 – Sam

0

您的函数_widgetDataService。RetrieveAsync有返回值,大概类型的任务< IEnumerable的< CollaboratorNetworkNode>>

你不应该把这些返回值在任务的阵列,但在任务<的IEnumerable < CollaboratorNetworkNode>>

var tasks = new Task<IEnumerable<CollaboratorNetWorkNode>>[][2]; 
tasks[0] = _widgetDataService.RetrieveAsync<CollaboratorNetworkNode>(
     "get_collaborator_nodes", portfolio, 
     recentFys, nodesSwitch); 

tasks[1] = _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>(
     "get_collaborator_edges", portfolio, recentFys); 
await Task.WhenAll(tasks); 
var nodes = tasks[0].Result.Select(pi=> new GraphNode 
{ 
    Id = pi.ProfileId, 
    ... 
}) 
数组
0

这是你的数组声明造成的问题。由于哈拉尔建议,应该用适当的Task<T>类型,而不是使用Task丢弃类型的信息:

var tasks = new Task<IEnumerable<CollaboratorNetworkNode>>[2]; 
tasks[0] = _widgetDataService.RetrieveAsync<CollaboratorNetworkNode>(
     "get_collaborator_nodes", portfolio, 
     recentFys, nodesSwitch); 
tasks[1] = _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>(
     "get_collaborator_edges", portfolio, recentFys); 
var results = await Task.WhenAll(tasks); 
// results[0] is IEnumerable<CollaboratorNetworkNode> 
// results[1] is IEnumerable<CollaboratorNetworkNode> 

var nodes = from pi in results[0] 
      select new GraphNode { Id = pi.ProfileId, Properties = pi, Labels = new[] { "Person" } }; 

我建议使用的await Task.WhenAll时可能(因为这个代码)的结果。如果不可能(即,如果任务是不同类型的),则应该使用await检索结果,而不是ResultResult将在AggregateException中包含任何异常,这使错误处理变得复杂。