2011-04-06 7 views
5

매우 분별력있는 사람으로부터 스레드에서 던져진 (그리고 잡히지 않은) 예외가 부모 스레드로 전파되고 있음을 들었습니다. 그게 사실이야? 이 같은 것을 시도했지만 생성 스레드에서 예외를 catch 할 수 없습니다.다중 스레드 응용 프로그램의 예외.

static void Main(string[] args) 
    { 
     ParameterizedThreadStart pts = 
      new ParameterizedThreadStart(ThreadMethod); 
     try 
     { 
      Thread t = new Thread(pts); 
      t.Start(new object()); 
      Console.ReadLine(); 
     } 
     catch (Exception ex) //the exception is not caught 
     { 
      Debugger.Break(); 
     } 
    } 


    static void ThreadMethod(object @object) 
    { 
     Thread.Sleep(2000); 
     throw new IndexOutOfRangeException(); 
     Thread.CurrentThread.Abort(); 
    } 
+0

나는 단지 당신이 예외가 사용 http://msdn.microsoft.com/en-us/library/system을 잡은 경우보고 싶은 경우는,에 발생 스레드에 던져 확신합니다. backgroundworker 대신 componentmodel.backgroundworker.runworkercompleted.aspx 완료 –

답변

10

스레드의 예외가 주 스레드의 컨텍스트로 전파되지 않습니다. 이것은 실제로 의미가 있습니다 - 예외가 throw 될 때까지 주 스레드는 일반적으로 예외 처리기가 포함 된 범위와 완전히 다른 범위에 있습니다.

AppDomain.UnhandledException에 연결하여 이러한 예외 (일반적으로 로그에 기록)를 포착 할 수 있습니다. 등의 Windows Forms 응용 프로그램의 차이를 포함한 자세한 내용은 해당 페이지,

1

아니요, 그렇지 않습니다. 스레드 예외를 잡으려면 Application.ThreadException을 사용해야합니다.

1

예외 처리에 대한 섹션 갖는 C에서 # 스레딩에 알맞은 자원은 Threading in C#

1

예외 호출 스택의 위쪽으로 전파한다.

특정 메소드에서 새 스레드를 시작하면 해당 메소드에 도달 할 때까지 위쪽으로 전파됩니다.

이 메서드는 catch하지 않으면 런타임 오류가 발생하여 catch되지 않는 예외가 발생합니다.

0

여기를 잡기 안전한 방법으로 그것을 처리하는 방법 중 하나입니다 참조 : 예외를 처리 할 수 ​​

BackgroundWorker bg = new BackgroundWorker(); 
object o; 
bg.DoWork += (c1,c2) => 
{   
     Thread.Sleep(2000);   
     throw new IndexOutOfRangeException(); 
}; 

bg.RunWorkerCompleted += (c3,c4) => 
{ 

if (((RunWorkerCompletedEventArgs)e).Error != null) 
    { 
     MessageBox.Show(((RunWorkerCompletedEventArgs)e).Error.Message); 
    } 
}; 
1

간단히 말해서, 그렇지 않습니다. 당신은 분명 옵션이 몇 가지 있습니다.의 #

  1. 새 스레드를 시작하는 방법에 로그 아웃 (생성 된 스레드에 대한 스택의 맨 위)
  2. 사용 비동기 대리자와 같은 구조,하는 것입니다 것 당신이 정상적인 방법으로 잡을 수있는 end invoke를 호출 할 때 예외를 리턴한다.
1

예외가 발생한 스레드에서만 예외가 발견 될 수 있습니다. 따라서 다른 스레드에서 예외를 throw해도 다른 스레드가이를 catch하지 않습니다.

"상위"스레드의 개념은 없습니다.

0

주 스레드가 다른 스레드의 완료를 기다리는 특수한 경우에 매우 간단한 해결책이 있습니다 (https://msdn.microsoft.com/en-us/library/58195swd(v=vs.110).aspx#Examples 참조). 클래스 예외 변수 만 필요합니다.

예외 처리기에서 완료된 수정 된 코드 샘플은 다음과 같을 수 있습니다.

using System; 
using System.Threading; 

class WaitOne 
{ 
    static AutoResetEvent autoEvent = new AutoResetEvent(false); 
    static Exception SavedException = null; 

    static void Main() 
    { 
     Console.WriteLine("Main starting."); 

     ThreadPool.QueueUserWorkItem(
      new WaitCallback(WorkMethod), autoEvent); 

     // Wait for work method to signal. 
     autoEvent.WaitOne(); 
     if (SavedException != null) 
     { 
      // handle this exception as you want 
     } 

     Console.WriteLine("Work method signaled.\nMain ending."); 
    } 

    static void WorkMethod(object stateInfo) 
    { 
     Console.WriteLine("Work starting."); 

     // Simulate time spent working. 
     try 
     { 
      Thread.Sleep(new Random().Next(100, 2000)); 
      throw new Exception("Test exception"); 
     } 
     catch (Exception ex) 
     { 
      SavedException = ex; 
     }    

     // Signal that work is finished. 
     Console.WriteLine("Work ending."); 
     ((AutoResetEvent)stateInfo).Set(); 
    } 
} 
관련 문제