为什么c#异常处理机制没有捕捉到win32异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1205426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 10:52:02  来源:igfitidea点击:

Why win32 exception are not caught by c# exception handling mechanism

c#winformsexception-handling

提问by Rohit Raghuvansi

I have a winforms application.Winforms start with Program.cs where we have main() defined.I have put this code in try-catch block.

我有一个 winforms 应用程序。Winforms 以 Program.cs 开头,其中我们定义了 main()。我已将此代码放在 try-catch 块中。

 [STAThread]
    static void Main()
    {
        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmSplash());
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            if (ex.InnerException != null)
            {
                MessageBox.Show(ex.InnerException.ToString());
            }
        }
    }

Whenever there is a win32 exception,this mechanism fails and unhandled exception message is thrown and application crashes.
I have 2 questions regarding this code:

每当出现 win32 异常时,此机制就会失败,并抛出未处理的异常消息并导致应用程序崩溃。
我有两个关于此代码的问题:

1) Why win32 exceptions are not caught.

1) 为什么没有捕获到 win32 异常。

2) Is it a good practice to catch exceptions at the highest level.

2) 在最高级别捕获异常是否是一个好习惯。

采纳答案by Mac

EDIT: as Pratikpointed out, the following answer applies to .NET 1.0 and .NET 1.1 only. Starting with .NET 2.0, non-CLS exception should be caught as a RuntimeWrappedException.

编辑:正如Pratik 所指出的,以下答案仅适用于 .NET 1.0 和 .NET 1.1。从 .NET 2.0 开始,非 CLS 异常应作为RuntimeWrappedException 捕获



Because Win32 exceptions do not derive from the .NET Exception class. Try :

因为 Win32 异常不是从 .NET Exception 类派生的。尝试 :

try {
} catch (Exception ex) {
    // .NET exception
} catch {
    // native exception
}

See Catch non-CLSCompliant exceptions in general handlersfor more information.

有关详细信息,请参阅在一般处理程序中捕获非 CLSCompliant 异常

回答by Frozenskys

You may need to catch as Win32Exception (or ExternalException) instead

您可能需要改为捕获 Win32Exception(或 ExternalException)

http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx

http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx

I seem to remember that Win32Exception inherits from ExternalException but ExternalException does not inherit from Exception so won't be caught by your code.

我似乎记得 Win32Exception 继承自 ExternalException 但 ExternalException 不继承自 Exception 所以不会被您的代码捕获。

Edit:See other answers for why this is wrong!

编辑:请参阅其他答案以了解为什么这是错误的!

Edit 2:As for the second part, as stated by AnthonyWJones It is good manners to let the user know that a problem has caused the application to close, however I would recommend using a plain English statement to the user, and logging the exception stack to a log file for your own use.

编辑 2:至于第二部分,如 AnthonyWJones 所述,让用户知道问题导致应用程序关闭是一种礼貌,但我建议向用户使用简单的英文语句,并记录异常堆栈到日志文件供您自己使用。

回答by AnthonyWJones

The execution of Application.Run is not throwing an error. That is happening on another thread (or at least asynchronously).

Application.Run 的执行不会引发错误。这发生在另一个线程上(或至少是异步的)。

Its good idea to inform the user in friendly way that the application has failed before it disapears completely, however its not a good idea to just catch then continue.

在应用程序完全消失之前以友好的方式通知用户该应用程序已经失败是一个好主意,但是它不是一个好主意,只是抓住然后继续。

回答by softveda

While I don't know why your catch block doesn't work try using the Application ThreadException Event. This should catch any error in application threads. Add an event handler before calling Application.Run.

虽然我不知道为什么您的 catch 块不起作用,但请尝试使用Application ThreadException Event。这应该会捕获应用程序线程中的任何错误。在调用 Application.Run 之前添加一个事件处理程序。

For your second answer definitely yes. I develop and maintain a enterprise winforms application that talk with a web service backend on background threads. If any webservice call crashes handle the application threadexception (and also appdomain unhandledexception) event, log and popup an error that business users can report and allow them to continue without crashing the application.

对于你的第二个答案肯定是。我开发并维护了一个企业 winforms 应用程序,该应用程序与后台线程上的 Web 服务后端进行通信。如果任何 webservice 调用崩溃处理应用程序线程异常(以及 appdomain unhandledexception)事件,记录并弹出一个错误,业务用户可以报告并允许他们继续而不会使应用程序崩溃。

回答by Christian Hayter

1) Win32 exceptions should be caught. Maybe the exception is being thrown from a background thread or the GC thread?

1) 应捕获 Win32 异常。也许异常是从后台线程或 GC 线程抛出的?

2) It depends on your app structure. For example, if your error notification UI was tied to the main form somehow (e.g. you need to invoke the UI thread from a worker thread), then it would be silly to display a UI in a code block outside the code that runs the message loop. However, if your code example is single-threaded then it would be fine.

2)这取决于您的应用程序结构。例如,如果您的错误通知 UI 以某种方式绑定到主窗体(例如,您需要从工作线程调用 UI 线程),那么在运行消息的代码之外的代码块中显示 UI 将是愚蠢的环形。但是,如果您的代码示例是单线程的,那就没问题了。

回答by Mac

Try subscribing to these events before your application starts (Application.Run) :

尝试在应用程序启动之前订阅这些事件 ( Application.Run) :

You could then get rid of your try catchblock.

然后你可以摆脱你的try catch障碍。



I think it is bad practice to catch exceptions at the highest level, but you cannot avoid it ! During development (Debug), those exceptions should not be caught and the application should do the nastiest thing possible (crash ?). In production (Release), you will want your application to degrade as nicely as possible even when unhandled exceptions occur. This is one of the few uses I found for the DEBUGpreprocessor variable.

我认为在最高级别捕获异常是不好的做法,但您无法避免!在开发(调试)期间,不应捕获这些异常,应用程序应尽可能做最糟糕的事情(崩溃?)。在生产(发布)中,即使发生未处理的异常,您也希望您的应用程序尽可能地降级。这是我发现DEBUG预处理器变量的少数用途之一。