RunContinuationsAsynchronously does not run continuations asynchronously

The .NET Framework 4.6 added a new enum type value, RunContinuationsAsynchronously, to the TaskCompletionSource and TaskCreationOptions enums. This value forces tasks to run asynchronously, and this helps to avoid deadlock situations. However, an issue has been discovered where, for some specific kinds of continuations (in particular when Task.WhenAll, Task.WhenAny, or TaskExtensions.Unwrap create the continuations), the option is ignored. Therefore, continuations may still run synchronously.

The following sample shows the problem. If the RunContinuationsAsynchronously value were functioning correctly, the two thread IDs that are printed out would never be the same, because the continuation would always be scheduled onto different threads.

using System;using System.Threading;using System.Threading.Tasks; class Program{    static void Main()    {        var mres = new ManualResetEventSlim();         Console.WriteLine(Environment.CurrentManagedThreadId);         var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);         var t = Task.WhenAll(tcs.Task);         t.ContinueWith(delegate        {            Console.WriteLine(Environment.CurrentManagedThreadId);            mres.Set();        }, TaskContinuationOptions.ExecuteSynchronously);         tcs.SetResult(true);        mres.Wait();    }}

There is currently no workaround for this issue. The Microsoft .NET Framework team is working on a solution to include in a future update. 


Article ID: 3118695 - Last Review: 11/24/2015 18:10:00 - Revision: 1.0

Microsoft .NET Framework 4.6.1

  • kbsurveynew kbexpertiseadvanced kbtshoot KB3118695