18

I have some code as follows:

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

Because MyMethod1 and MyMethod2 are called Asynchronously watch.Stop() gets called at the wrong time. How I can ensure that .Stop gets called and logged after MyMethod1 and MyMethod2 finish BUT ensure that MyMethod3 does not have to wait.

I want to keep all Stopwatch functionality in my Start() method and not have the logging in any of my 3 methods i.e. MyMethod1, MyMethod2 and MyMethod3

i3arnon
  • 113,022
  • 33
  • 324
  • 344
Bob
  • 4,236
  • 12
  • 45
  • 65

3 Answers3

25

You can use the Task.Factory.ContinueWhenAll method.

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

If you're targeting for .NET 4.5 and upper, you can also use the method Task.WhenAll. It returns a task that will complete when all of the passed Task objects have completed.

Task.WhenAll(t1, t2).ContinueWith(t => watch.Stop());
Ilya
  • 21,871
  • 8
  • 73
  • 92
-1

You need create a new Thread that will handle the logging issue. This logging thread will wait on EventWaitHandle.WaitAll(threadsEventWaitHandles) that will contain all the threads EventWaitHandles. Something like that :

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

    EventWaitHandle.WaitAll(threadsEventWaitHandles);

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

And also the methods MyMethod1, MyMethod2 will signal to the loging thread whene they finish. Something like that :

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

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

So you can ensure that MyMethod3 does not have to wait.

Jacob
  • 751
  • 1
  • 6
  • 18
-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);
    }
gleng
  • 6,185
  • 4
  • 21
  • 35