在ContinueWith(anotherTask)+ C#任务并行库中共享变量

时间:2018-02-01 05:33:15

标签: c# task-parallel-library

我使用continuationWith(anotherTask)创建一个任务,如下所示。我想找出第一项任务完成工作所需的时间。我分享变量" task1StartedDateTime"在task1和子任务之间。这会没有任何问题吗?

public static void MyMethod()
{
    var task1StartedDateTime = DateTime.Now;
    var task1 = doWorkAsync();
    task1.ContinueWith(t1 => {
        var task1TookTime = DateTime.Now - task1StartedDateTime;
        Console.WriteLine($"Task 1 took {task1TookTime}");
        //Some other work of this child task
    });
}

2 个答案:

答案 0 :(得分:6)

是的,它会起作用。但是,使用StopWatch类应该更好,因为这是一种更准确有效的方法,用于计算方法的运行时间,处理机器上运行的任何内容。有关后一个参数的更多信息,请查看here

var stopwatch = StopWatch.StartNew();
var task1 = doWorkAsync();
task1.ContinueWith(t1 => {
    stopwatch.Stop();
    Console.WriteLine($"Task 1 took {stopwatch.EllapsedMilliseconds} ms.");
   //Some other work of this child task
}

答案 1 :(得分:3)

是的,您可以在lambda中使用捕获的变量 - 以这种方式关闭的captured variables将被提升为匿名类实例,以确保它们可以比它们声明的方法更长,并允许它们之间的共享外部方法和延续。

但是,您应该使用Stopwatch来衡量时间 - 它更准确。

在.Net 4.5及更高版本中,您还可以选择将.ContinueWith中的续点替换为awaited continuation - 这有额外的保证,并且更易于阅读:

public static async Task MyMethod()
{
    var sw = new Stopwatch();
    sw.Start();
    await doWorkAsync();
    var task1TookTime = sw.Elapsed;
    Console.WriteLine($"Task 1 took {task1TookTime}");
    //Some other work of this child task
}

(虽然请注意,如果等待MyMethod,则任务只会完成一次doWorkAsync并且计时器记录完成,这与原始实现不同。