症状
.NET Framework 4.6 添加新的枚举类型值, RunContinuationsAsynchronously, TaskCompletionSource和TaskCreationOptions枚举。该值将强制任务异步运行,这有助于避免死锁情况。然而,一个问题已经被发现,对于延续 ( Task.WhenAll、 Task.WhenAny或TaskExtensions.Unwrap在创建延续任务时尤其) 是在某些特定类型,将忽略此选项。因此,延续可能仍以同步方式运行。
下面的示例显示了此问题。如果RunContinuationsAsynchronously的值正常的两个线程打印出来的 Id 将永远不会变,因为总是会到不同的线程上安排延续。 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(); } }解决方案
目前尚无解决此问题的方法。Microsoft.NET Framework 工作组在将来的更新中包括的解决方案。