2012-03-08 2 views
4

У меня есть следующая задачаTPL Как правильно отменить задачу

cancelSource = new CancellationTokenSource(); 
token = cancelSource.Token; 

string strDbA = textBox1.Text; 
string strDbB = textBox2.Text; 

// Start duplication on seperate thread. 
asyncDupSqlProcs = 
    new Task<bool>(state => 
     UtilsDB.DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB), "Duplicating SQL Proceedures"); 
asyncDupSqlProcs.Start(); 
asyncDupSqlProcs.ContinueWith(task => 
{ 
    switch (task.Status) 
    { 
     // Handle any exceptions to prevent UnobservedTaskException.    
     case TaskStatus.Faulted: 
      // Error-handling logic... 
      break; 
     case TaskStatus.RanToCompletion: 
      if (asyncDupSqlProcs.Result) 
       Utils.InfoMsg(String.Format(
     "SQL stored procedures and functions successfully copied from '{0}' " + 
        "to '{1}'", strDbA, strDbB)); 
      break; 
     case TaskStatus.Canceled: 
      Utils.InfoMsg("Copy cancelled at users request."); 
      break; 
    } 
}, TaskScheduler.FromCurrentSynchronizationContext()); 

В методе DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB) у меня есть стандартное обнаружение отмены:

if (_token.IsCancellationRequested) 
    _token.ThrowIfCancellationRequested(); 

Событие отмены является нажатие кнопки на главной формы, внутри события щелчка У меня есть:

try 
{ 
    cancelSource.Cancel(); 
    asyncDupSqlProcs.Wait(); 
} 
catch (AggregateException aggEx) 
{ 
    if (aggEx.InnerException is OperationCanceledException) 
     Utils.InfoMsg("Copy cancelled at users request."); 
} 

, но я могу показаться, что поймаю AggregateException, что я здесь делаю неправильно?

Редактировать: Внутри метода DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB) Я могу поймать OperationCancelledException, но я смущен о том, как с ним обращаться. Весь пример, который я видел, обрабатывает печать «Operation Canceled ...» и т. Д. В потоке пользовательского интерфейса в событии, вызвавшем отмену. Каков наилучший способ захвата отмены и передачи его обратно в пользовательский интерфейс/вызывающий поток?

+0

В чем исключение, которое не обрабатывается? –

+0

Хммм, я получаю исключение на моем тестовом коде. Вы уверены, что метод DuplicateSqlProcsFrom() не работает быстро? –

+0

И в каком контексте это происходит? другой поток? Пользовательский интерфейс? –

ответ

1

Чтобы получить OperationCancelledException, его необходимо бросить с помощью того же токена, что и один передан конструктору Задачи:

new Task<bool>(state => 
    UtilsDB.DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB), 
     "Duplicating SQL Proceedures", token); 
2

Скорее всего, это связано с режимом Just My Code (по умолчанию для проверки) в Visual Studio. Отладчик ломается, прежде чем TPL сможет наблюдать за исключением. Попробуйте снять флажок и посмотреть, не очистит ли это все (Tools-> Options-> Debugging-> General, затем снимите флажок)