2011-01-23 60 views
5

我有螺纹这样,以后我看到例如link text抛出异常的线程C#

ThreadStart _threadStart = new ThreadStart(delegate() 
{ 
     try 
     { 
      threadFunction(httpContext); 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
}); 
Thread _thread = new Thread(_threadStart); 
    _thread.Start(); 

当有异常情况发生就这么想的重新抛出在启动它的线程。 那么我做错了什么或如何去做?

注:感谢所有评论先进

+6

注意你应该永远* *重新抛出异常就像你在那里做。只要在catch块中做`throw;`就足够了...... – Joey 2011-01-23 13:09:28

+0

我知道我会抛出自定义的异常,并从消息 – Hiyasat 2011-01-23 13:23:53

+1

中继承“System.Exception”。你必须抛出一个* new *异常,并添加你想要添加的信息。作为InnerException传递* original *异常。只有在增加的信息具有较高的价值时才能做到这一点,因为它使故障排除更加困难。 – 2011-01-23 14:51:24

回答

7

将引发异常,但那只会结束该线程。异常不会在启动它的线程中重新引发。

1

的异常被抛出,但我猜你没有看到它,因为它是在另一个线程抛出。因此,UI线程(或者其他线程调用另一个线程)不能捕获异常,因为它看不到它。

如果您登录的例外,例如文件,我敢肯定,你会看到它。 :)

+0

异常会在任何线程被看到。我认为根本没有异常 - 线程正常完成。 – 2011-01-23 13:20:59

+0

我确定有异常发生,但不会抛出主线程 – Hiyasat 2011-01-23 13:25:03

2

你确定引发异常吗?如果一个线程发生异常并失败,整个应用程序将崩溃,您可以注意到使用AppDomain.CurrentDomain.UnhandledException事件(请注意,事件触发时,您无法阻止应用程序结束,但可以清理资源并保存关键数据 - 请参阅事件文档以获取更多信息)。

这就提出了一个顶级异常指示一个大问题任何线程:

但是,从您提到的线程引用accepted answer

您应该尝试记录异常,和/或通知其他线程此线程已失败。

6

我认为问题的心脏是要了解一个线程中发生的异常不会被传递到处理上的调用线程。

例如,假设你有一个反叛方法:

private static void RebelWithoutACause() 
{ 
    throw new NullReferenceException("Can't touch this!"); 
} 

比方说,你创建一个新的线程,在程序调用此方法,并且是安全的程序员,你决定信封一个工作try/catch块:

private static void Main(string[] args) 
{ 
    try 
    { 
     var thread = new Thread(RebelWithoutACause); 
     thread.Start(); 
     thread.Join(); 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.ToString()); 
    } 
} 

但是,如果你在调试器中运行它,你会发现,你永远也没有机会了catch块,而是该线程将被杀死,调试器会抱怨你有一个未处理的异常。

您需要选择如何处理异常,但需要在每个线程输入方法内部进行处理。典型的处理包括记录细节,通过UI通知用户,并尽可能优雅地关闭应用程序。

0

可能做这样的事情:

const int numThreads = 8; 
    Thread[] threads = new Thread[numThreads]; 
    Exception[] threadsExceptions = new Exception[numThreads]; 
    for (int i = 0; i < numThreads; i++) { 
     threadsExceptions[i] = null; 
     int closureVariableValue = i; 
     ThreadStart command =() => 
     { 
      try 
      { 
       throw new ArgumentException("thread_" + closureVariableValue + "'s exception"); 
      }catch(Exception any) 
      { 
       threadsExceptions[closureVariableValue] = any; 
      } 
     }; 
     threads[i] = new Thread(command); 
     threads[i].Start(); 
    } 
    for(int i = 0; i < numThreads; i++) 
    { 
     threads[i].Join(); 
     if (threadsExceptions[i] != null) 
     { 
      throw threadsExceptions[i]; 
     } 
    }