Satheesh K
Satheesh K

Reputation: 67

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

I create a task with continuationWith(anotherTask) as below. I want to find out the time taken for completing its work by the first task. I share the variable "task1StartedDateTime" between task1 and child task. Will this work without any issues?

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

Upvotes: 3

Views: 766

Answers (2)

StuartLC
StuartLC

Reputation: 107407

Yes, you can use captured variables in a lambda - captured variables closed over in this way will be promoted to an anonymous class instance, to ensure they can outlive the method they are declared in, and to allow sharing between the outer method and the continuation.

However, you should use aStopwatch for measuring time - it is more accurate.

In .Net 4.5 and later, you also have the option to replace the continuation in .ContinueWith to an awaited continuation - this has additional guarantees, and is easier to read:

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
}

(Although note that if MyMethod is awaited, that the Task will only complete once doWorkAsync and the timer logging is complete, which differs from your original implementation).

Upvotes: 3

Christos
Christos

Reputation: 53958

Yes it will work. However it should be better to make use of the StopWatch class, since this is a more accurate and efficient way of calculating elapsed time of a method, process whatever running on a machine. For more info related to the latter argument, please have a look 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
}

Upvotes: 6

Related Questions