14

我有一些代码如下:

public void Start()
{
    var watch = new Stopwatch();
    watch.Start();

    Task.Factory.StartNew(MyMethod1);
    Task.Factory.StartNew(MyMethod2);

    watch.Stop();
    Log(watch.ElapsedMilliseconds);
    Task.Factory.StartNew(MyMethod3);
}

因为 MyMethod1 和 MyMethod2 被异步调用 watch.Stop() 在错误的时间被调用。我如何确保在 MyMethod1 和 MyMethod2 完成后调用和记录 .Stop 但确保 MyMethod3 不必等待。

我想在我的 Start() 方法中保留所有 Stopwatch 功能,并且不让我的 3 种方法中的任何一种都登录,即 MyMethod1、MyMethod2 和 MyMethod3

4

3 回答 3

22

您可以使用该Task.Factory.ContinueWhenAll方法。

watch.Start();
var t1 = Task.Factory.StartNew(MyMethod1);
var t2 = Task.Factory.StartNew(MyMethod2);
Task.Factory.ContinueWhenAll(new [] {t1, t2}, tasks => watch.Stop());

如果您的目标是 .NET 4.5 及更高版本,您也可以使用方法Task.WhenAll. 它返回一个任务,该任务将在所有传递的 Task 对象完成后完成。

Task.WhenAll(t1, t2).ContinueWith(t => watch.Stop());
于 2013-10-15T12:47:52.943 回答
-1

您需要创建一个新的线程来处理日志记录问题。此日志记录线程将等待EventWaitHandle.WaitAll(threadsEventWaitHandles)包含所有线程 EventWaitHandles。类似的东西:

private void LoggingThread()
{
    var watch = new Stopwatch();
    watch.Start();

    EventWaitHandle.WaitAll(threadsEventWaitHandles);

    watch.Stop();
    Log(watch.ElapsedMilliseconds);
}

而且这些方法MyMethod1, MyMethod2将在完成时向日志线程发出信号。类似的东西:

private void MyMethod1()
{
    //... your code
    EventWaitHandle.Set();
}

private void MyMethod2()
{
    //... your code
    EventWaitHandle.Set();
}

因此,您可以确保 MyMethod3 不必等待。

于 2013-10-15T13:09:08.060 回答
-2
    public void Start()
    {
        var watch = new Stopwatch();
        watch.Start();

        Task.Factory.StartNew(MyMethod1);
        Task.Factory.StartNew(MyMethod2);

        Task.WaitAll(); // Wait for previous tasks to finish

        watch.Stop();
        Log(watch.ElapsedMilliseconds);
        Task.Factory.StartNew(MyMethod3);
    }
于 2013-10-15T12:39:07.627 回答