简体   繁体   English

在没有catch块的情况下捕获异常

[英]Catching exceptions without a catch block

I'm working in a legacy project (read: refactoring is not an option) that is throwing ApplicationException s. 我正在处理一个抛出ApplicationException的旧项目(阅读:重构不是一种选择)。

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

Context 上下文

I'm a relatively new dev. 我是一个相对较新的开发人员。 Basic throwing/catching exceptions explicitly makes sense to me. 基本的抛出/捕获异常对我明确地有意义。 Even the concept of exceptions bubbling up the call stack to a different catch statement feels intuitive. 甚至将调用堆栈冒泡到另一个catch语句的异常概念也很直观。

Beyond that I know the CLR is capable of.. something. 除此以外,我知道CLR可以.. This line is particularly confusing (from this article ) 这行特别令人困惑(来自本文

The exception is passed up the stack until the application handles it or the program terminates. 异常会在堆栈中传递,直到应用程序对其进行处理或程序终止。

I cannot find a single catch statement in this entire solution, which would leave me to think that the exception would terminate the process, but I'm seeing an error message on the front end instead - process runs on. 我在整个解决方案中找不到单个catch语句,这让我觉得异常将终止该进程,但是我在前端看到一条错误消息-进程继续运行。

The top of my call stack is spinning up a new thread and above that is external code. 我的调用堆栈的顶部是一个新线程,上面是外部代码。 I would show more code if it weren't proprietary. 如果不是专有的,我会显示更多代码。

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

The Question 问题

Is it possible that the thread that was spun up died, and the parent thread is what's ultimately propagating an error message and processing the exception? 旋转的线程是否有可能死亡,而父线程最终是传播错误消息并处理异常的原因?

If so, how does this transfer of control take place in .NET or whatever relevant technology handles it? 如果是这样,控制权的转移是如何在.NET或任何相关技术中进行的?

If you're throwing exceptions on the UI, the the call stack has a try-catch frame on it from System.Windows.Forms.NativeWindow.Callback , which is usually the root of the UI thread: 如果在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;
    }

From there, it invokes the Application.ThreadException handler. 从那里,它调用Application.ThreadException处理程序。 A default handler is installed that informs you of the exception. 已安装默认处理程序,该处理程序会通知您该异常。 After that, the exception is usually swallowed and your UI is given the chance to continue running. 之后,通常会吞下该异常,并且您的UI有机会继续运行。

The exception handling must be happening at the AppDomain level (as I am running .NET 4.5.1). 异常处理必须在AppDomain级别上进行(因为我正在运行.NET 4.5.1)。

Ultimately the AppDomain is what manages the various threads and handles the flow of control in this scenario. 最终,在这种情况下, AppDomain是管理各种线程并处理控制流的对象。

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

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