J'expérimente le support des tâches dans .NET 4.0 - spécifiquement avec le support de continuation. Ce que je suis perplexe, c'est que je ne peux pas comprendre comment obtenir une continuation avec le drapeau TaskContinuationOptions.OnlyOnCanceled
à exécuter. Si je fais un ThrowIfCancellationRequested
dans ma routine de travail, il semble seulement se propager hors de la continuation comme une faute au lieu d'une opération d'annulation. Par exemple, étant donné ce code:Bibliothèque parallèle de tâches - Comment obtenir une continuation avec TaskContinuationOptions.OnlyOnCanceled to Fire?
using System;
using System.Threading;
using System.Threading.Tasks;
namespace TaskExp1
{
class Program
{
static void Main()
{
var n = 10000;
DumpThreadId("main method");
var cts = new CancellationTokenSource();
var task = Task.Factory.StartNew<int>(_ => Sum(cts.Token, n),
cts.Token);
task.ContinueWith(t =>
{
DumpThreadId("ContinueWith Completed, ", newline:false);
Console.WriteLine("The result is " + t.Result);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
task.ContinueWith(t =>
{
DumpThreadId("ContinueWith Faulted, ", newline: false);
Console.WriteLine(t.Exception.InnerExceptions[0].Message);
}, TaskContinuationOptions.OnlyOnFaulted);
task.ContinueWith(_ =>
{
DumpThreadId("ContinueWith Cancelled, ");
}, TaskContinuationOptions.OnlyOnCanceled);
Console.WriteLine("Computing sum of " + n + " ...");
Thread.SpinWait(100000);
cts.Cancel();
Console.WriteLine("Done.");
Console.ReadLine();
}
static int Sum(CancellationToken cancelToken, int n)
{
DumpThreadId("from Sum method");
int sum = 0;
for (; n > 0; n--)
{
Thread.SpinWait(500000);
if (n == 10000) cancelToken.ThrowIfCancellationRequested();
checked { sum += n; }
}
return sum;
}
static void DumpThreadId(string msg = "", bool newline = true)
{
var formattedMsg = String.Format("ThreadId: {0} {1}",
Thread.CurrentThread.ManagedThreadId, msg);
if (newline) formattedMsg += "\n";
Console.Write(formattedMsg);
}
}
}
Ce sorties:
ThreadId: 9 main method
Computing sum of 10000 ...
Done.
ThreadId: 10 from Sum method
ThreadId: 10 ContinueWith Faulted, The operation was canceled.
Comment quitter ma méthode travailleur (Somme) de telle sorte que la poursuite OnlyOnCanceled
est congédié?
Wow qui semble subtile mais logique - en utilisant _! = Pour utiliser(). Merci! –