症状

.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 工作组在将来的更新中包括的解决方案。


Need more help?

Expand your skills
Explore Training
Get new features first
Join Microsoft Insiders

Was this information helpful?

How satisfied are you with the translation quality?
What affected your experience?

Thank you for your feedback!

×