Development Tip

BackgroundWorker의 처리되지 않은 예외

yourdevel 2020. 10. 29. 20:06
반응형

BackgroundWorker의 처리되지 않은 예외


내 WinForms 앱은 여러 BackgroundWorker 개체를 사용 하여 데이터베이스에서 정보를 검색합니다. 오랫동안 실행되는 데이터베이스 쿼리 중에 UI가 차단되지 않은 상태로 유지되고 나를 위해 스레딩 모델을 단순화하기 때문에 BackgroundWorker를 사용하고 있습니다.

이러한 백그라운드 스레드 중 일부에서 가끔 DatabaseExceptions가 발생하고 디버깅하는 동안 작업자 스레드에서 이러한 예외 중 하나 이상을 목격했습니다. 나는 이러한 예외가 때때로 예상하는 것이 합리적이라고 생각하는 시간 초과라고 확신합니다.

내 질문은 이러한 백그라운드 작업자 스레드 중 하나에서 처리되지 않은 예외가 발생하면 어떻게되는지에 대한 것입니다.

다른 스레드에서 예외를 잡을 수 없다고 생각하지만 WorkerCompleted 메서드가 실행될 것으로 예상 할 수 있습니까? 예외를 조사 할 수있는 BackgroundWorker의 속성이나 메서드가 있습니까?


작업에서 코드에서 처리 할 수없는 예외가 발생하면는 예외를 BackgroundWorker포착하여 RunWorkerCompleted이벤트 처리기 로 전달 합니다. 여기서 해당 예외 는의 Error 속성으로 노출됩니다 System.ComponentModel.RunWorkerCompletedEventArgs. Visual Studio 디버거에서 실행중인 경우 디버거는 처리되지 않은 예외가 발생한 DoWork 이벤트 처리기의 지점에서 중단됩니다.

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork.aspx


나는 BackgroundWorker수년에 걸쳐 완전히 사용 하고 있으며 깊이 알고 있습니다.

최근, 내는 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.Resultif를 얻지 마십시오 e.Cancelled = True.
  • 을하지 마세요 e.Result경우 e.Error없는 null(또는 Nothing**)

** 이것은 내가 그리워하는 곳입니다. e.Resultif e.Erroris not null(또는 Nothing) 을 사용하려고하면 처리되지 않은 예외가 발생합니다.


UPDATE : 에서 e.ResultGET 속성 .NET 설계가를 확인하기 위해 e.Error, 첫째, 가지고있는 경우 오류 그 때부터 같은 예외를 다시 throw합니다 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원하는 곳 어디에서나 쉽게 액세스 할 수 있습니다 .


기본적으로 BackgroundWorker에 의해 포착되어 저장됩니다. MSDN에서 :

작업에서 코드에서 처리하지 않는 예외가 발생하면 BackgroundWorker는 예외를 포착하여 RunWorkerCompleted 이벤트 처리기로 전달합니다. 여기서 System.ComponentModel.RunWorkerCompletedEventArgs의 Error 속성으로 노출됩니다. Visual Studio 디버거에서 실행중인 경우 디버거는 처리되지 않은 예외가 발생한 DoWork 이벤트 처리기의 지점에서 중단됩니다.


이미 언급했듯이 :

작업에서 코드에서 처리하지 않는 예외가 발생하면 BackgroundWorker는 예외를 포착하여 RunWorkerCompleted 이벤트 처리기로 전달합니다. 여기서 System.ComponentModel.RunWorkerCompletedEventArgs의 Error 속성으로 노출됩니다.

이것은 원래 스레드와 상호 작용할 때마다 중요합니다. 예를 들어, 예외의 결과를 폼의 어떤 종류의 레이블로 작성하려면 BackgroundWorker의 DoWork에서 예외를 포착하지 않고 대신 RunWorkerCompletedEventArgs의 e.Error를 처리해야합니다.

리플렉터를 사용하여 BackgroundWorker 코드를 분석하면 매우 간단하게 처리되는 것을 볼 수 있습니다. DoWork는 try-catch 블록에서 실행되고 예외는 RunWorkerCompleted로 전달됩니다. 이것이 내가 DoWork 이벤트에서 항상 모든 예외를 포착하는 '선호'방법에 동의하지 않는 이유입니다.

요컨대, 원래의 질문에 답하려면 :

-RunWorkerCompleted를 항상 해고 할 수 있습니다.

다른 스레드에서 예외를 확인하려면 RunWorkerCompleted의 e.Error사용하십시오 .


이것은 디버거가 연결되지 않은 상태에서만 작동합니다. Visual Studio에서 실행할 때 디버거는 DoWork 메서드에서 처리되지 않은 예외를 포착하고 실행을 중단하지만 계속을 클릭하면 RunWorkerCompleted에 도달하고 예외를 읽을 수 있습니다. e.Error 필드를 통해.

참고 URL : https://stackoverflow.com/questions/258662/unhandled-exceptions-in-backgroundworker

반응형