RunContinuationsAsynchronously 不会异步运行延续

应用对象
.NET Framework 4.6.1

症状

.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团队正在研究一个解决方案,以包含在将来的更新中。