【问题标题】:How to ensure all tasks have been executed and query the final results如何确保所有任务都已执行并查询最终结果
【发布时间】:2016-06-03 17:10:24
【问题描述】:

我正在使用任务来执行计算密集型操作。 PerformCalculation 方法。主父任务使用任务工厂创建三个子任务并开始执行。每个子任务应返回 List<Dictionary<int,double>>

List<double> paramList = new List<double>{ 2, 2.5, 3};

CancellationTokenSource cts = new CancellationTokenSource();

Task parent = new Task(() =>
{
    var tf = new TaskFactory<List<Dictionary<int, double>>>(cts.Token, TaskCreationOptions.AttachedToParent,
    TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);

    var childTasks = new[] {
        tf.StartNew(() => PerformCalculation(cts.Token, paramList[0],Task.CurrentId)),
        tf.StartNew(() => PerformCalculation(cts.Token, paramList[1],Task.CurrentId)),
        tf.StartNew(() => PerformCalculation(cts.Token, paramList[2],Task.CurrentId)) //3rd entry
        };

子任务执行成功后的结果应该是List&lt;Dictionary&lt;int, double&gt;&gt;的形式。

现在我的要求是编写一个 lambda 表达式,该表达式将在所有子任务完成执行后查询其结果并填充到另一个列表中

即列表列表 (List&lt;List&lt;Dictionary&lt;int, double&gt;&gt;&gt;)

// When all children are done, get the value returned from the
// non-faulting/canceled tasks. 
tf.ContinueWhenAll(childTasks, completedTasks => 
                   completedTasks
                   .Where(t => t.Status == TaskStatus.RanToCompletion)**??Need HELP HERE ???**),CancellationToken.None)
,TaskContinuationOptions.ExecuteSynchronously);

});

【问题讨论】:

    标签: c# .net lambda .net-4.0 task


    【解决方案1】:

    我会稍微回避一下这个问题,因为所有这些 API 基本上都已过时(或者至少不适合“主流”场景)。这实际上相当简单:

    var childTasks = new[] {
        Task.Run(() => PerformCalculation(cts.Token, paramList[0],Task.CurrentId)),
        Task.Run(() => PerformCalculation(cts.Token, paramList[1],Task.CurrentId)),
        Task.Run(() => PerformCalculation(cts.Token, paramList[2],Task.CurrentId)),
        };
    
    var results = Task.WhenAll(childTasks).Result;
    

    TaskFactory 是一种相当深奥的类型,我从未见过在野外使用过。应避免附加子任务,因为它们添加了不明显的依赖关系。这些都不是错误,而是气味。

    【讨论】:

    • 我不能使用 await,因为我的限制是我必须使用 .NET 4.0
    • 您可以将 await 与 4.0 一起使用,但我已将其编辑掉。在任何情况下,您可能会注意到使用 await 对于此答案不是必需的。这能回答你的问题吗?
    • Task.Run() 在 .NET 4.0 中不可用,但是我必须使用 Task.Factory.StartNew>>(() => PerformCalculation( cts.Token,paramList[0],Task.CurrentId))。还有任何想法可以替代 Task.WhenAll(childTasks).Result
    • 对...这些在 4.0 中也不可用...尝试 Task.WaitAll 后跟 childTasks.Select(t => t.Result) 以提取结果。那将是您查询中的“需要帮助”行。无需检查状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    相关资源
    最近更新 更多