【问题标题】:Catching exceptions without a catch block在没有 catch 块的情况下捕获异常
【发布时间】:2016-02-05 16:27:00
【问题描述】:

我在一个遗留项目中工作(阅读:重构不是一种选择),它抛出了ApplicationExceptions。

throw new ApplicationException(string.Format("More than one type found with the name {0} in {1}", typeName, assemblies));

上下文

我是一个相对较新的开发者。 Basic 明确地抛出/捕获异常对我来说很有意义。甚至将调用堆栈中的异常冒泡到不同的 catch 语句的概念也很直观。

除此之外,我知道 CLR 有能力……一些东西。这行特别令人困惑(来自this article)

异常向上传递到堆栈,直到应用程序处理它或程序终止。

我在整个解决方案中找不到单个 catch 语句,这让我认为异常会终止进程,但我在前端看到一条错误消息 - 进程继续运行。

我的调用堆栈的顶部正在启动一个新线程,其上方是外部代码。如果它不是专有的,我会展示更多代码。

Dim installThread As New Thread(CType(Sub() InstallPackageAsyncInner(appsToOverride, package, parameters), Threading.ThreadStart))

问题

是否有可能被启动的线程死亡,而父线程最终传播错误消息并处理异常?

如果是这样,这种控制转移是如何在.NET 或任何相关技术处理的?

【问题讨论】:

  • 我意识到我可能只是自己调试了橡皮鸭,但我仍然会发布这个以防它帮助其他人。
  • 只有信息碎片加上无关紧要的琐事,而所有需要的都在发布指南中非常清楚地列出,例如一个最小但完整的例子。
  • 如果你找不到单个异常处理程序,你脑海中浮现的就是有人在 appdomain 级别注册了未处理的异常......代码中是否有任何 UnhandledException += new UnhandledExceptionEventHandler?
  • 未处理的异常处理程序或异常在线程池线程中抛出,我们正在运行 .net 4.5。
  • 是的,这是一个非常模糊的问题,但是像“在 appdomain 级别注册未处理的异常”之类的东西至少给了我一些我可以用谷歌搜索的东西。谢谢@NDJ!我将结束这个问题,因为我无法明确我所问的内容

标签: c# .net multithreading exception


【解决方案1】:

如果您在 UI 上抛出异常,调用堆栈上有一个来自 System.Windows.Forms.NativeWindow.Callback 的 try-catch 帧,这通常是 UI 线程的根:

    private IntPtr Callback(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam) {

        // Note: if you change this code be sure to change the 
        // corresponding code in DebuggableCallback below!

        Message m = Message.Create(hWnd, msg, wparam, lparam);

        try {
            if (weakThisPtr.IsAlive && weakThisPtr.Target != null) {
                WndProc(ref m);
            }
            else {
                DefWndProc(ref m);
            }
        }
        catch (Exception e) {
            OnThreadException(e);
        }
        finally {
            if (msg == NativeMethods.WM_NCDESTROY) ReleaseHandle(false);
            if (msg == NativeMethods.WM_UIUNSUBCLASS) ReleaseHandle(true);
        }

        return m.Result;
    }

从那里,它调用Application.ThreadException 处理程序。安装了一个默认处理程序,通知您异常。之后,异常通常会被吞没,您的 UI 将有机会继续运行。

【讨论】:

    【解决方案2】:

    异常处理必须发生在 AppDomain 级别(因为我运行的是 .NET 4.5.1)。

    最终,AppDomain 负责管理各种线程并在此场景中处理控制流。

    【讨论】:

      猜你喜欢
      • 2011-08-25
      • 2016-10-12
      • 2014-04-12
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      • 2019-07-12
      • 1970-01-01
      • 2016-06-26
      相关资源
      最近更新 更多