2014-09-03 4 views
0

Итак, я пытаюсь отменить задачу при возникновении ошибки и выдать taskcancelationsource.cancel (true), который, в свою очередь, выдает исключение.Задание задачи при ошибке перед завершением всех задач

Проблема заключается в том, что при возникновении ошибки отмена не запускается до тех пор, пока все задачи не будут завершены. IsInError.Value устанавливается в событие NotifyCollectionChanged, которое запускается, когда сообщение об ошибке добавляется в коллекцию сообщений.

Я должен выполнить «ожидание Task.WhenAll (tasks)», который, вероятно, удерживает все, пока все они не будут выполнены, и я могу оценить, была ли ошибка.

return Task.Run(async() => 
{ 
    concreteModel.TotalStepCount.Value = 11; 
    try 
    { 
     if (args.EventArgs.EtlOperationType == EtlOperationType.StandardVehicle) 
     { 
      concreteModel.CompletedStepCount.Value += 1; 
     } 
     List<Task> tasks = new List<Task>(); 
     tasks.Add(Task.Run(() => StandardVehicleConversionStorageProxy.ConvertData(container, importRawData), taskCancellationToken)); 

     await Task.WhenAll(tasks); 
     if (concreteModel.IsInError.Value) 
     { 
      taskCancellationTokenSource.Cancel(true); 
     } 
    } 
    finally 
    { 
     conversionOperation.IsInProgress.Value = false; 
     if (subscription != null) 
     { 
      subscription.Dispose(); 
     } 
    } 
}, taskCancellationToken); 

И ошибка отмены задачи решаются в вызывающей процедуре ...

private async Task<bool> convertAsync() 
{ 
    try 
    { 
     await ConversionOperations.Single(x => x.OperationType == EtlOperationType.StandardVehicle).ConvertAsync(Container, _cancellationSource, ImportRawData); 
    } 
    catch (TaskCanceledException ex) 
    { 
     // handle the throw task cancellation exception 
     ex.Task.Dispose(); 
     return false; 
    } 
    finally 
    { 
     IsConverting.Value = false; 
    } 
    return true; 
} 

ответ

1

Вы проверка ошибки после вызова await Task.WhenAll(tasks);. Это не произойдет, пока все задачи не будут завершены.

Вместо этого вы должны вызвать taskCancellationTokenSource.Cancel(true); в обработчике событий, пока задачи все еще запущены.

Вам также необходимо пройти taskCancellationToken в StandardVehicleConversionStorageProxy.ConvertData и проверить токены отмены с помощью CancellationToken.IsCancellationRequested или CancellationToken.ThrowIfCancellationRequested() для обработки запроса отмены.

+0

Звучит логично, спасибо! ЗадачаCancellationToken может быть передана в ConvertData, которая выполняет функцию ResponsibilityChain. Я думаю, что мне приходится бросать ошибку задачи на каждом из шагов, где установлен IsInError. – RobDog888