【问题标题】:Sharing variable in ContinueWith(anotherTask) + C# Task Parallel LibraryContinueWith(anotherTask) + C# 任务并行库中的共享变量
【发布时间】:2018-07-11 09:04:25
【问题描述】:

我使用 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
    });
}

【问题讨论】:

    标签: c# task-parallel-library


    【解决方案1】:

    是的,它会起作用。然而,最好使用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
    }
    

    【讨论】:

    • 谢谢克里斯托斯。
    【解决方案2】:

    是的,您可以在 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,并且计时器记录已完成,这与您的原始实现不同)。

    【讨论】:

    • 谢谢斯图尔特。
    • 你的也回答了我的问题。但我无法在堆栈溢出中将 2 个响应标记为我的答案...
    猜你喜欢
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多