Ho la seguente configurazione nel mio codice che utilizza il TPL:TPL cancellazione continuazione mai invitato annullato Task
- Un campo nella mia classe: private CancellationTokenSource _cancellationTokenSource;
- Questo CancellationTokeSource viene instatiated ogni volta che creo un compito TPL che utilizza quel particolare CancellationToken
I compiti TPL actualy simile a questa:
var dataRetrievalTask = new Task<List<myType>>(() =>
{
// retrieve data and do something
foreach (var a in retrievalMethod())
{
if (_cancellationTokenSource.Token.IsCancellationRequested)
_cancellationTokenSource.Token.ThrowIfCancellationRequested();
// do something if not cancelled
}
}
return filledListOfMyType;
}, _cancellationTokenSource.Token);
// define what shall happen if data retrievel finished without any problems
var writingLoadedDataToGridTask = dataRetrievalTask.ContinueWith(task =>
{
// do something in case we ran to completion without error
}, _cancellationTokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, currentScheduler);
// what to do in case cancellation was performed
var loadingDataCancelledTask = dataRetrievalTask.ContinueWith(task =>
{
someLabel.Text = "Data retrieval canceled.";
},_cancellationTokenSource.Token, TaskContinuationOptions.OnlyOnCanceled, currentScheduler);
// what to do in case an exception/error occured
var loadingDataFaulted = dataRetrievalTask.ContinueWith(task =>
{
someLabel.Text = string.Format("Data retrieval ended with an Error.");
}, _cancellationTokenSource.Token, TaskContinuationOptions.OnlyOnFaulted, currentScheduler);
// when any of the continuation tasks ran through, reset ui controls/buttons etc
Task.Factory.ContinueWhenAny(new[] { writingLoadedDataToGridTask, loadingDataCancelledTask, loadingDataFaulted }, task =>
{
// reset controls and all that
}, _cancellationTokenSource.Token, TaskContinuationOptions.None, currentScheduler);
dataRetrievalTask.Start();
Ora il mio problema è che quando il _cancellationTokenSource.Cancel Il metodo() viene chiamato da qualche parte (nel gestore di eventi .Click del pulsante Annulla) che il particolare corpo/metodo loadingDataCancelledTask non viene chiamato.
Cosa sto facendo di sbagliato qui? Sto usando e consegnando la stessa istanza _cancellationTokenSource.Token ... e tutto il resto (le attività 'writeLoadedDataToGridTask' e 'loadingDataFaulted' & il seguente 'Task.Factory.ContinueWhenAny (new [] {writingLoadedDataToGridTask, loadingDataCancelledTask, loadingDataFaulted}, task => ...' blocco) non funzionano davvero. Solo la cancellazione non è così. qualcuno vedere/sapere perché?
oh mio, ora che lo dici .. ha senso, sì. Molte grazie!! –
Quindi cosa significa "TaskContinuationOptions.OnlyOnCanceled"? Non funzionerà mai? – Jasper
Significa che viene eseguito quando l'attività * di base * viene annullata. Ma puoi anche annullare la continuazione. Se non vuoi che questo non passi un token di cancellazione ad esso. – usr