2010-06-01 6 views
6

예외가 보조 스레드에서 발생하는 경우 주 스레드에서 예외를 catch하는 방법은 무엇입니까? 당신은 Application.ThreadException 이벤트 핸들러를 추가 할 수 있습니다예외가 보조 스레드에서 발생하는 경우 주 스레드에서 예외를 catch하는 방법?

private void button1_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     Thread th1 = new Thread(new ThreadStart(Test)); 
     th1.Start();    
    } 
    catch (Exception) 
    { 

    } 
} 

void Test() 
{ 
    for (int i = 0; i < 100; i++) 
    { 
     Thread.Sleep(100); 

     if (i == 2) 
      throw new MyException(); 
    } 
} 
+0

수 없습니다. 하나는 예외가 발생할 때까지 주 스레드에서 try ... catch가 이미 완료되었습니다. –

답변

3

:

시나리오에 대한 코드

은 아래와 같습니다

조 맞습니다.

이 이벤트는 윈도우가 윈도우 스레드를 양식 에서 발생하는 다른 처리되지 않은 예외를 처리 할 수 ​​ Forms 응용 프로그램을 할 수 있습니다 : 위의 창은 내가 윈도우 형태를 가정 한 코드를 형성 감안할. 이벤트 처리기를 스레드 예외 이벤트에 연결하여 알 수없는 상태로 둡니다. 가능한 경우 예외는 구조적 예외 처리 블록으로 처리해야합니다.

Unexpected Errors in Managed Applications

+1

이 답변이 잘못되었다고 생각합니다. AFAIK (하지만 테스트 할 시간이 없다), Application.ThreadException은 UI 스레드의 예외 (예 : WinForms 컨트롤의 이벤트 핸들러에서 처리되지 않은 예외) 만 처리합니다. 작업자 스레드의 예외는 AppDomain.UnhandledException 이벤트 처리기에서 처리 할 수 ​​있지만 핸들러는 기본 UI 스레드가 아니라 작업자 스레드에서 실행됩니다. WinForms UI 스레드에서 작업자 스레드의 예외를 처리하려는 경우 가장 좋은 솔루션은 내 대답에 표시된대로 BackgroundWorker를 사용하는 것입니다. – Joe

+0

은 Windows Forms처럼 ASP.NET 코드 일 수 있습니다. 의사 코드 일 수도 있습니다. –

+0

참. 현재 Winforms에서 작업 중이므로 모든 것이 winforms처럼 보입니다! –

2

BackgroundWorker 사용을 참조하십시오.

BackgroundWorker는보고 예외를 포함하여 기본 UI 스레드와 백그라운드 작업자 스레드 간의 통신을위한 인프라를 제공합니다. button_click 이벤트 핸들러에서 스레드를 시작하는 것보다 거의 항상 좋은 해결책입니다.

+0

"??????????" BackgroundWorker는보고 예외를 포함하여 기본 UI 스레드와 백그라운드 작업자 스레드 간의 통신을위한 인프라를 제공합니다. OP의 샘플처럼 button_click 이벤트 핸들러에서 스레드를 시작하는 것보다 거의 항상 더 나은 솔루션입니다. – Joe

+2

확실한 ... 그래서 답변에 넣어 :). 참조가 나쁘지는 않지만 설명이 더 좋습니다! – Kiril

0

모든 예외를 전체적으로 트래핑하는 데 관심이있는 경우 비동기 대리인을 사용하여 정보를 버블 링 할 수도 있습니다.

스레드 B에 here 말하자면

트랩 예외를 참조 A.에게 예외로부터의 데이터가 처리 될 때 구체적으로 타겟팅 할 수있는 그런 방식으로 스레드까지 버블 정보 비동기 위임을 사용한다.

0

@codeka가 말했듯이, 당신은 할 수 없습니다. 하지만 보조 스레드에서 catch 블록의 UI 요소 (MessageBox 오류 표시)를 수행하려는 경우 이와 같이 묶을 수 있습니다. 당신이 당신의 시험 방법에 예외 처리를 추가하는 것을 고려하고있다 예외를 처리해야 BackgroundWorker

Invoke(new Action(() => 
{ 
    MessageBox.Show("Message"); 
})); 
1

를 사용하는 경우 더 나은.

무료 서적에서이 접근법 (및 다른 접근 방식)에 대해 설명합니다. '예외 처리'섹션으로 스크롤하십시오.

0

당신은 할 수 있습니다 (현재 중 & hellip, 문제는 원래 질문했을 때이 사용할 수 없음) asyncawait를 사용

private async void button1_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     await Task.Run(Test); 
    } 
    catch (Exception) 
    { 

    } 
} 

Task.Run() 방법은 Test() 방법은 작업자 스레드에서 실행하게됩니다. 해당 스레드에서 처리되지 않은 예외가 throw 된 경우 Task은 해당 예외를 await 문에서 기다리고있는 스레드로 다시 전파합니다.

관련 문제