繁体   English   中英

在线程C#中抛出异常

[英]throw an Exception in thread C#

我有线程这样,在我看到示例链接文本后

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

当异常发生时,它不会在启动它的线程中重新抛出。 那么我做错了什么或怎么做?

注意:感谢所有高级评论

抛出异常,但这只会结束线程。 在启动它的线程中不会重新抛出异常。

我认为问题的核心是要理解线程中发生的异常不会传递给调用线程进行处理。

例如,假设您有反叛方法:

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通知用户,以及尽可能优雅地关闭应用程序。

你确定抛出了异常吗? 如果线程因异常而失败,整个应用程序将崩溃,您可以注意到使用AppDomain.CurrentDomain.UnhandledException事件(请注意,在事件触发时,您无法阻止您的应用程序结束,但可以清除 -增加资源并保存关键数据 - 有关更多信息,请参阅事件文档。

但是,引用您提到的主题中接受的答案

任何引发顶级异常的线程都表明存在很大问题。

您应该尝试记录异常,和/或发信号通知该线程失败的其他线程。

抛出异常,除了我猜你没有看到它,因为它被抛出在另一个线程上。 因此,UI线程(或任何线程调用其他线程)无法捕获异常,因为它没有看到它。

例如,如果您将异常记录到文件中,我相信您会看到它。 :)

也许做这样的事情:

   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];
       }
   }

我想也许你应该看看使用BackgroundWorker类。 您可以订阅RunWorkerCompleted事件,它具有将包含您的异常的Error属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM