什么时候 .NET WinForms 应用程序中的异常可以被吃掉而不被捕获或冒泡为 Windows 异常?
在代码中的几个地方,我们注意到,如果在调试器下运行,它将显示代码中存在未处理的异常,但是如果在调试器外部运行,它将完全忽略异常,就好像它被捕获一样。 我们有一个异常处理程序,它会弹出一个错误提交对话框,该对话框连接到 Application.ThreadException 和 AppDomain.CurrentDomain.UnhandledException 而这些似乎都没有抓住他们。 我们还记录异常情况,但日志中没有显示任何内容。
造成这种情况的可能原因有哪些?
编辑:它似乎并不取决于异常抛出的类型,而是取决于抛出的位置。 这是通过添加来测试的:
throw new Exception("Test Exception");
它将显示在调试器下,但不会显示在外部,因此在我们的例子中,它不是 ThreadAbortedException 或任何依赖于它的特定类型的异常。
In several places in our code, we notice that if running under debugger it'll show that there's an unhandled exception in the code, however if running outside the debugger it will just ignore the exception completely as if it were caught. We have an exception handler that pops up an error submit dialog that's hooked up to Application.ThreadException and AppDomain.CurrentDomain.UnhandledException
And neither of those appear to be catching them either. We also log our exceptions and nothing appears in the log.
What are some possible reasons for this?
Edit: It seems that it isn't dependent on the type of exception throw, but rather where it is thrown. This was tested by just adding:
throw new Exception("Test Exception");
It'll show up under debugger but doesn't show up outside, so in our case it's not a ThreadAbortedException or anything that's dependent on it being a specific type of exception.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
有一些特殊的异常不会被冒泡或捕获,听起来您正在处理其中之一:请参阅 ThreadAbortException
There are some special exceptions that don't get bubbled up or caught, it sounds like you're dealing with one of them: see ThreadAbortException
发现可能发生这种情况的一个地方是 UnhandledException 事件处理程序中存在异常。 看到这一点的一个简单方法是:
在 Form.Load 事件处理程序中抛出任何旧的异常。
在 Application.ThreadException 事件中放置类似于以下内容的内容:
在调试器下,它将显示您的异常未由用户代码处理,然后它将在 ThreadException 处理程序中显示空引用异常,但如果您在外部运行它调试器只会像处理异常一样吞掉异常。
Found one place where this could occur is if there's an exception in the UnhandledException event handler. An easy way to see this is this:
In the Form.Load event handler throw any old exception.
In the Application.ThreadException event put something similar to the following:
Under debugger it'll show your exception was unhandled by user code, and then after that it'll show a null reference exception in the ThreadException handler, but if you run it outside the debugger it'll just swallow the exception like it was handled.
如果您尝试从创建该控件的不同线程修改 Windows 窗体控件的属性,您将收到 InvalidOperationException 如果附加了调试器,但否则会被静默忽略。
有关此问题的更多信息可以在此处找到:
http:// /msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx
If you try to modify the properties of a Windows Form control from a different thread the control was created in, you get an InvalidOperationException if there is a debugger attached, but it gets silently ignored otherwise.
More info on the issue can be found here:
http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx
您的代码是从框架调用的。
有时,框架将其调用包装在异常处理程序中。
因此,如果代码中存在异常,框架可能会捕获并忽略它(如果框架中有异常处理程序)。
也许调试器将其显示为“未处理”,因为尽管框架中有一个处理程序,但您的代码中没有处理程序? 或者,因为框架中的处理程序有些奇怪,例如它是一个非托管的结构化异常处理程序?
Your code is invoked from the framework.
Sometimes, the framework wraps its calls in an exception handler.
So, if there's an exception in your code, it may be (if there's an exception handler there in the framework) caught and ignored by the framework.
Maybe the debugger shows it as "unhandled" because, although there's a handler in the framework, there's no handler in your code? Or, because there's something strange about the handler in the framework, for example that it's an unmanaged, structured exception handler?
您使用的是.Net 1.0/1.1吗? 从 1.1 到 2.0 的过渡过程中,行为发生了巨大的变化。 在此之前,您创建的线程或 ThreadPool 线程上引发的异常将被框架默默吞下,并且线程将退出。 值得庆幸的是,这种行为现已得到修复。
来自 MSDN:
Are you using .Net 1.0/1.1? There was a huge change in behaviour in the transition from 1.1 to 2.0. Before then exceptions raised on threads you created or ThreadPool threads would be swallowed silently by the frameworok and the thread would exit. Thankfully this behaviour has now been fixed.
From MSDN:
这里有点延伸,但是您是否只是将调试器设置为在引发异常时中断,而不仅仅是针对未处理的异常?
Kind of a stretch here, but could it be that you just have set your debugger to break when an exception is thrown, and not only for the unhandled ones?