0

When I chain a method using ContinueWith and if that method uses async Action, then why is the chained method not waited for completion when we do Task.WhenAll?

For example following code

var str1 = "str1";
var str2 = "str2";
var task0 = Task.Run( async ()=> { 
                await Task.Delay(1000);
                return "changed";
            });
var task1 = task0.ContinueWith(async prevTask => {
                await Task.Delay(5000);
                str1 = prevTask.Result;
            });
var task2 = task0.ContinueWith(prevTask => {
                Task.Delay(1000).Wait();
                str2 = prevTask.Result;
            });

await Task.WhenAll(task0, task1, task2);
Console.WriteLine(str1);
Console.WriteLine(str2);

produces output

str1
changed

But when I try to do same with another task with async action but blocking call to Task.Delay, then that method works fine. For example, adding task 3 as

....
var str3 = "str3";
var task3 = task0.ContinueWith(async prevTask => {
                Task.Delay(2500).Wait();
                str3 = prevTask.Result;
            });

await Task.WhenAll(task0, task1, task2, task3);
Console.WriteLine(str1);
Console.WriteLine(str2);
Console.WriteLine(str3);

produces following output

str1
changed
changed 

While debugging, I also saw the state of task1 as 'Ran to completion', which I don't understand why. Seems like await inside ContinueWith is causing the task to assume it has completed, but I don't understand why?

Link to functioning code: http://rextester.com/WFRTKY13796

Shishir Gupta
  • 1,512
  • 2
  • 17
  • 32
  • 2
    `ContinueWith` does not support `async` delegates, thus resulting task represent only first synchronous part of asynchronous delegate. You need to call `Unwrap()`, if you want get task which represent completion of asynchronous delegate as whole. – user4003407 Jun 26 '18 at 16:27
  • 1
    There are very few situations where it's appropriate or useful to use `ContinueWith`. You're almost always better off using `await` to schedule continuations to tasks. Using `ContinueWith` directly is *much* harder to do correctly. – Servy Jun 26 '18 at 17:09

0 Answers0