Search code examples
c#task-parallel-librarycontinuewith

ContinueWith Method - How to understand it exactly?


So i have e.g. this code here:

initialTask.ContinueWith((argument) => { ... });

I understand the second Task is executed once the first one is finished. I have to provide the second Task with an argument though, which is also of Type Task.

Is this 'argument' the OLD task or is this an entirely new instance?

E.g. when i want to handle a cancellation of the First Task in the Second Task, do i have to call:

initialTask.IsCanceled

or

argument.IsCanceled

?


Solution

  • Is this 'argument' the OLD task or is this an entirely new instance?

    Yes, it's a reference to the same Task instance parameter passed as the parameter to .ContinueWith (i.e. "Old") - you can verify this as per below:

    var initialTask = Task.Delay(1000);
    initialTask.ContinueWith(t2 => {Debug.Assert(t2 == initialTask);}).Wait();
    

    The reason why the task instance is passed in is to allow you to access the completed state and output of the Task. But, before accessing the result of t2, you'll need to see whether it throws an exception (t2.IsFaulted), cancelled (t2.IsCanceled) etc which becomes messy very quickly.

    Instead, now that C# supports the async / await syntax, that you should find the code easier to read, and easier to handle exceptions etc, if you rewrite your code as follows:

    async Task MyMethod()
    {
       try
       {
          var initialResult = await SomeInitialTask();
          var secondResult = await SecondTask(initialResult); // instead of .ContinueWith and accessing t2.Result
          ... etc.
       }
       catch (Exception ex)
       {
          // Much easier than checking .IsFaulted on each nested task
       }
    }