如何确保在子任务中完成父任务的回调

时间:2015-12-01 13:18:55

标签: c# task-parallel-library task

internal int SomeFunction()
{
    Task<AddResult> task1 = new Task<AddResult>(() => AddFunction());
    task1.Start();            
    Task<FuncResult> task2 = task1.ContinueWith(task => func1(task1.Result), TaskContinuationOptions.OnlyOnRanToCompletion);       
    Task task3 = task2.ContinueWith(task => func2(task2.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
    Task task4 = task3.ContinueWith(task => func3(task2.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
    return 200;
} 

void回调(字节响应) {

}

在上面的func1和func2函数中会向设备发送一些数据,并在回调函数中收到响应。 func3会将数据保存到数据库中,但在此之前我需要确保完成所有回调。我怎样才能做到这一点。

2 个答案:

答案 0 :(得分:1)

利用Task.WhenAll()并将您的个人任务存储在一个集合中。

List<Task<t>> _tasks = new List<Task<t>>();

// Now add your tasks...
_tasks.Add(Task<DeviceInfo>(() => AddNodeToNetwork((Modes)mode)));
// Next task, etc.

最后等待所有任务。这将在调用线程上运行awaiter。

await Task.WhenAll(_tasks);

这将从线程池线程运行awaiter。

await Task.WhenAll(_tasks).ConfigureAwait(false);

答案 1 :(得分:0)

我认为诀窍是在lambda表达式中引用名为'task'的参数。这是你要关注的任务,所以如果你引用'task'而不是'task1','task2','task3'等,那么通过询问task.Result,你可以保证前一个任务已被执行。

唯一的另一件事是你需要等待task4(最后一个)完成,你可以通过调用Task.WaitAll(new [] { task4 })

来完成
internal int SomeFunction()
{
    Task<AddNodeResult> task1 = new Task<DeviceInfo>(() => AddNodeToNetwork());
    task1.Start();            
    Task<ZWNode> task2 = task1.ContinueWith(task => GetCommandClassesVersions(task.Result), TaskContinuationOptions.OnlyOnRanToCompletion);       
    Task task3 = task2.ContinueWith(task => GetManufacturerSpecific(task.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
    Task task4 = task3.ContinueWith(task => PersistAddedNode(task.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
    return 200;
}     

如果这不能编译,请道歉 - 只需在此输入文本编辑器!