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

Sharing variable in ContinueWith(anotherTask) + C# Task Parallel Library

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

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

是的,它会起作用。然而,最好使用 StopWatch class,因为这是计算方法运行时间的更准确和有效的方法,在机器上处理任何 运行。有关后一个参数的更多信息,请查看 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
}

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

但是,您应该使用 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 并且计时器记录已完成,这与您的原始实现不同。