Фоновый работник: исключение при отмене - PullRequest
0 голосов
/ 26 июня 2009

У меня есть фоновый работник, которого можно отменить.

Нормальные потоки прерываются, когда переменная CancelPending становится равной true (в ответ на взаимодействие с пользователем в пользовательском интерфейсе, который вызывает рабочий. выброшен)

Поэтому, когда работник возвращается, я хочу иметь возможность различать исключения, которые были выброшены, когда работник был отменен (чтобы игнорировать их) из исключений, выданных, когда работник не был отменен (чтобы сообщить о них в пользовательский интерфейс).

Мой код следующий (извините за микс c # / vb ...):

Рабочий класс:

Public Class ClassBaseGetObjectsWorker
    Inherits System.ComponentModel.BackgroundWorker


 Protected Overrides Sub OnDoWork(ByVal e As System.ComponentModel.DoWorkEventArgs)
        Try

            Dim cpt As Int16 = 0
            While cpt < 5
                System.Threading.Thread.Sleep(1000)
                cpt = cpt + 1
                If CheckForCancellation() Then
                    'Simulating exception due to cancel
                    Throw New Exception("Exception du to cancel !")
                End If
            End While

        Catch exc As Exception
            e.Cancel = Me.CancellationPending
            Throw exc
        End Try

    End Sub
End Class

Перезвоните:

void setObjSetCollWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
    if (e.Cancelled) {
        resultLabel.Text += "Canceled";
        //e.Error is selently ignored
    }
    else {
        if (e.Error != null) {
            //Reporting errors arising during normal (uncanceled) flow
            throw e.Error.InnerException;
        }
        else {
            //Worker process finished without error or being canceled.
            updateUIAfterBackgroundJob();
        }
    }
}

Затем, когда я выполняю работника worker.CancelAsynch (), для e.Cancelled устанавливается значение false (что не соответствует ожиданиям) при завершении вызова. Если я закомментирую «Trow exc» в работнике, если я проверю опять же, e.Cancelled правильно установлено в значение true.

Итак, какой самый чистый способ получить требуемую информацию, а именно: я хочу знать, было ли выброшено исключение, всплывающее в завершенном обработчике, когда работник находился в состоянии cancellationPending или нет.

(извините за мой плохой английский)

1 Ответ

0 голосов
/ 26 июня 2009

Если лучший способ структурировать код в вашей реализации OnDoWork () - генерировать исключение при обнаружении отмены, выполните следующие действия:

Создать CancelException:

public class CancelException: Exception {}

Бросьте это исключение CancelException, когда вы обнаружите, что отмена ожидает рассмотрения:

if(CheckForCancellation()) throw new CancelException();

Добавьте пробную версию кода в вашем OnDoWork () - метод:

protected override void OnDoWork(DoWorkEventArgs e){
  try{
    //...
  }
  catch(CancelException){
    // silently return
    return;
  }
}

Таким образом, ваш код будет подчиняться фоновому контракту BackgroundWorker (который должен возвращаться из OnDoWork () при обнаружении отмены, а не генерировать исключение), и теперь свойство Cancelled должно быть таким, как вы ожидаете

...