Я полностью использую BackgroundWorker
в течение многих лет и действительно знаю это глубоко.
Совсем недавно My RunWorkerCompleted
не ловит e.Error
, когда я просто Throw New Exception("Test")
в DoWork
. Однако необработанное исключение поднято. Поймать DoWork
не лучшая практика, поэтому e.Error
не имеет смысла.
Когда я пытаюсь создать новый Form
с новым BackgroundWorker
, e.Error
в RunWorkerCompleted
успешно обработан. Там должно быть что-то не так в моем сложном BackgroundWorker
.
После нескольких дней поиска и отладки, попробуйте ошибку. Я нашел это в моем RunWorkerCompleted
:
- Сначала проверьте
e.Error
, затем e.Cancelled
и, наконец, e.Result
- Не получите
e.Result
, если e.Cancelled = True
.
- Не получите
e.Result
, если e.Error
не null
(или Nothing
) **
** Здесь я скучаю. Если вы пытаетесь использовать e.Result
, если e.Error
не null
(или Nothing
), будет выдано необработанное исключение.
UPDATE:
В свойстве e.Result
get .NET сначала его проверяют на e.Error
, если получено сообщение об ошибке, то они выдают то же исключение из DoWork
. Вот почему мы получаем необработанное исключение в RunWorkerCompleted
, но на самом деле исключение происходит от DoWork
.
Вот лучшая практика для RunWorkerCompleted
:
If e.Error IsNot Nothing Then
' Handle the error here
Else
If e.Cancelled Then
' Tell user the process canceled here
Else
' Tell user the process completed
' and you can use e.Result only here.
End If
End If
Если вы хотите, чтобы объект был доступен всем DoWork, ProgressChanged и RunWorkerCompleted, используйте следующее:
Dim ThreadInfos as Dictionary(Of BackgroundWorker, YourObjectOrStruct)
Вы можете легко получить доступ к ThreadInfos(sender).Field
где угодно.