Sintomi
Il 4.6 di.NET Framework consente di aggiungere un nuovo valore di tipo enum, RunContinuationsAsynchronously, di enum TaskCompletionSource e TaskCreationOptions . Questo valore impone attività da eseguire in modo asincrono e questo consente di evitare situazioni di deadlock. Tuttavia, è stato individuato un problema in cui, per alcuni tipi specifici di continuazioni (in particolare quando le continuazioni di creare Task.WhenAll, Task.WhenAnyo TaskExtensions.Unwrap ), l'opzione viene ignorata. Di conseguenza, le continuazioni possono comunque eseguire in modo sincrono.
Nell'esempio riportato di seguito viene illustrato il problema. Se il valore di RunContinuationsAsynchronously sono stati funziona correttamente, i due thread ID che sono stampati mai saranno gli stessi, in quanto la continuazione sarà sempre programmata su thread diversi.
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();
}
}
Risoluzione
È attualmente disponibile alcuna soluzione per questo problema. Il team di Microsoft.NET Framework sta lavorando su una soluzione in modo da includere in un aggiornamento futuro.