如何解包Task <ienumerable>以处理结果?

时间:2016-08-20 14:36:33

标签: c# async-await

我正在设置Task[]数组,因此我可以像这样使用Task.WhenAll()

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" } };

我收到错误消息:

  

无法投射类型的对象   &#39; System.Threading.Tasks.Task&#39; 1 [System.Collections.Generic.IEnumerable&#39; 1 [Nete.Ireport.Models.ViewModels.CollaboratorNetworkNode]]&#39;   输入   &#39; System.Collections.Generic.IEnumerable&#39; 1 [Nete.Ireport.Models.ViewModels.CollaboratorNetworkNode]&#39;

如果我试着这样做:

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

我无法编译,因为我得到了红色波浪形的:

  

任务不包含Select和最佳扩展名的定义   方法重载&#34; DynamicQueryable.Select(IQueryable,string,params   object []需要一个IQueryable类型的接收器。

我们只是尝试运行这两个检索服务,每个服务都是10秒。所以我们的电话是20秒。 我现在在13到15秒内到达断点。 所以,如果我可以让它工作,我已经剃了5到7秒。

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

如何完成此方法?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

您的函数Task<IEnumerable<CollaboratorNetworkNode>>具有返回值,可能是Task

类型

您不应将这些返回值放在Task<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, ... })

的数组中
    $validator = Validator::make($request->all(), [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    if ($validator->fails()) {
        return redirect('post/create')
                    ->withErrors($validator)
                    ->withInput();
    }

答案 2 :(得分:0)

这是导致问题的数组声明。正如Harald建议的那样,它应该使用适当的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中包装任何异常,这会使错误处理变得复杂。