症状
.NET Framework 4.6 向 TaskCompletionSource 和 TaskCreationOptions 枚举添加了新的枚举类型值 RunContinuationsAsynchously。 此值强制任务异步运行,这有助于避免死锁情况。 但是,已发现一个问题:对于某些特定类型的延续, (特别是当 Task.WhenAll、Task.WhenAny 或 TaskExtensions.Unwrap 创建延续) 时,选项将被忽略。 因此,延续可能仍可以同步运行。
下面的示例演示了问题。 如果 RunContinuationsAsynchronously 值正常运行,则打印出的两个线程 ID 永远不会相同,因为延续将始终安排在不同的线程上。
using System;
使用 System.Threading;
using System.Threading.Tasks;
class Program
{
static void 主 ()
{
var mres = new ManualResetEventSlim () ;
Console.WriteLine (Environment.CurrentManagedThreadId) ;
var tcs = new TaskCompletionSource<bool> (TaskCreationOptions.RunContinuationsAsynchronously) ;
var t = Task.WhenAll (tcs。任务) ;
t.ContinueWith (delegate
{
Console.WriteLine (Environment.CurrentManagedThreadId) ;
夫人设置 () ;
}, TaskContinuationOptions.ExecuteSynchronously) ;
Tcs。SetResult (true) ;
夫人等待 () ;
}
}
解决方法
目前没有此问题的解决方法。 Microsoft.NET Framework团队正在研究一个解决方案,以包含在将来的更新中。