現象
.NET Framework の 4.6 では、 TaskCompletionSource 、 TaskCreationOptions列挙型に、新しい列挙型の値、 RunContinuationsAsynchronouslyが追加されます。デッドロックを回避できるので、この値を強制的に非同期的に実行するタスク。ただし、問題が検出された場所に、(特定のTask.WhenAll、 Task.WhenAny、またはTaskExtensions.Unwrapは、継続を作成するとき) に継続のうちの特定の種類がいくつか、オプションは無視されます。したがって、継続は同期的に実行も可能性があります。
次の例は、問題を示しています。RunContinuationsAsynchronously値が正しく機能している場合、2 つのスレッド 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 チームは、今後のアップデートでは、解決策に取り組んでいます。