如何:生成 UnhandledException?

发布于 2024-09-02 18:03:44 字数 2345 浏览 12 评论 0 原文

我使用此代码来捕获 WinForm 应用程序 UnhandledException。

[STAThread]
static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new
      System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

    // Set the unhandled exception mode to force all Windows Forms errors 
    // to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException += 
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    try
    {
        Application.Run(new MainForm());
    } catch....

在那里我将尝试重新启动应用程序。现在我的问题是模拟这样的异常。我在尝试之前尝试过(在 main 中): throw new NullReferenceException("test"); VS 捕获了它。

在 MainForm 代码中也尝试使用按钮 :

    private void button1_Click(object sender, EventArgs ev)
    {         
        ThreadPool.QueueUserWorkItem(new WaitCallback(TestMe), null);
    }

    protected void TestMe(object state)
    {
        string s = state.ToString();
    }

没有帮助,VS 捕获了它,即使在发布模式下也是如此。

  • 最后,我应该如何强制应用程序生成 UnhandleldException
  • 我可以在 CurrentDomain_UnhandledException重新启动应用程序吗?
  • 如何生成 ThreadException

附言。

如果我在 VS 之外启动 Windows 通用窗口

遇到应用程序“MyApplication” 一个错误,应该是 已关闭...blabla...发送报告/不 发送。

然而,我想要VS输入这个方法(...Domain_Unhahdled...)

编辑: 重新启动应用程序时,是否可以禁用 Windows 崩溃消息,如下所示: 替代文本 http://byfiles.storage.msn .com/y1pOhWnAAXfMYtJH2VNa5iL0l1hjAqNHD2VmVnl8nN6L1oQC_xHkyHCJxhMc1ZLxLOH9ZXfZoo5zX8?合作伙伴=作家< /a> ?

代码:

static void CurrentDomain_UnhandledException(object sender, 
    UnhandledExceptionEventArgs e)
{
    // Since we can't prevent the app from terminating
    // log this to the event log.
    Logger.LogMessage(ERROR, errorMsg);
    Application.Restart();

I use this code to catch the WinForm application UnhandledException.

[STAThread]
static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new
      System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

    // Set the unhandled exception mode to force all Windows Forms errors 
    // to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException += 
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    try
    {
        Application.Run(new MainForm());
    } catch....

There I will try to restart the application. Now my problem is to simulate a exception like this. I tried before try (in main): throw new NullReferenceException("test"); VS caught it.

Tried also in MainForm code with button :

    private void button1_Click(object sender, EventArgs ev)
    {         
        ThreadPool.QueueUserWorkItem(new WaitCallback(TestMe), null);
    }

    protected void TestMe(object state)
    {
        string s = state.ToString();
    }

did not help, VS caught it, even in Release mode.

  • How should I, finally, force the application generate UnhandleldException?
  • Will I be able to restart the application in CurrentDomain_UnhandledException?
  • How can I generate a ThreadException?

PS.

If I launch outside the VS a windows generic window

Application MyApplication" encountered
a error and should be
closed...blabla...Send report/Don't
send.

I want, however, VS enter this method (...Domain_Unhahdled...)

EDIT:
When restarting the application, Is it possible to disable the windows crash message appearing like:
alt text http://byfiles.storage.msn.com/y1pOhWnAAXfMYtJH2VNa5iL0l1hjAqNHD2VmVnl8nN6L1oQC_xHkyHCJxhMc1ZLxLOH9ZXfZoo5zX8?PARTNER=WRITER
?

Code:

static void CurrentDomain_UnhandledException(object sender, 
    UnhandledExceptionEventArgs e)
{
    // Since we can't prevent the app from terminating
    // log this to the event log.
    Logger.LogMessage(ERROR, errorMsg);
    Application.Restart();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

机场等船 2024-09-09 18:03:44

我仍然不完全确定我理解这个问题,但有几点需要提及:

  • Application.ThreadExceptionApplication.SetUnhandledExceptionMode 仅适用于 Windows 窗体线程。任意 ThreadPool 线程实际上并不是 Windows 窗体线程,即使在 Winforms 应用程序中也是如此,因此这两行代码无效。

  • 使用AppDomain.CurrentDomain.UnhandledException注册事件捕获ThreadPool线程上发生的异常。

  • 但是UnhandledException 事件实际上无法处理异常。到那时再阻止进程终止就为时已晚了,如果后台线程上发生异常,这种情况总是会发生(除非您启用了旧版 .NET 1.1 行为,但是……不要这样做。)此事件是实际上只适用于日志记录或清理。

我自己使用与您类似的测试代码对此进行了测试,并验证了异常“处理程序”内的代码确实执行。但应用程序仍然会崩溃,而且你无法阻止它。

更新:我将再做一次尝试,仅此而已。

如果您的目标是让无人值守的应用程序始终运行,那么您只有三个选择:

  1. 正确处理异常。这是迄今为止最好的选择可能唯一正确的解决方案。挂钩 AppDomain.UnhandledException处理异常。当控件进入该事件处理程序时,您的应用程序已经崩溃了。您无法再保存它。

    从后台线程转义的未处理异常是代码中的灾难性错误,需要修复。从后台线程中逃逸的未处理异常是代码中的灾难性错误,需要修复。从后台线程转义的未处理异常是代码中的灾难性错误,您需要修复它。请不要再发表“我不在乎”的评论 - 您需要开始< /em> 关心。

  2. 请 Windows礼貌为您重新启动应用程序。与尝试从崩溃处理程序重新启动不同,这是一个非常糟糕的主意,原因太多而无法完全列举(数据损坏、无限重启循环、资源泄漏、操作系统不稳定等),注册重新启动实际上允许这种情况以半受控的方式发生。正如我在评论中提到的,与 .NET 中的此 API 互操作。您可以在应用程序启动后立即进行注册,而不是在应用程序崩溃并且您的应用程序处于不受信任状态时进行注册。

  3. 创建一个监督服务来监视您的应用程序并在应用程序崩溃时重新启动它。出于前两点讨论的许多原因,这仍然很糟糕,但你至少有一定程度的稳定性的战斗机会。

    通过使用命名互斥体,在主管中等待该互斥体,并观察 WAIT_ABANDONED 状态(AbandonedMutexException 。网)。仅当拥有互斥锁的进程终止而不释放它时,即出现未处理的异常时,才会出现放弃状态。通过更多的互操作黑客,您还可以检测并关闭崩溃窗口。

这些是你的选择。我强烈建议您处理后台线程上的异常,因为从后台线程转义的未处理异常是您需要修复的代码中的灾难性错误。如果它来自外部组件,您可以如果没有发现,那么灾难性的错误就在该组件中,您应该考虑将其报告给作者或使用其他组件。

如果应用程序不够稳定而无法实际继续运行,那么简单地提出“此应用程序必须始终运行并且应该完全忽略致命崩溃”的要求并不能使这种情况成为可能。崩溃就是崩溃。你不会设计一辆汽车,让它在发动机突然熄火时立即重新启动。您能做的最好的事情就是要求值得信赖的操作员(无论是人工操作员、操作系统还是某些监控软件)代表其重新启动应用程序。

这个问题的变体似乎经常出现 - 基本上,“我的应用程序不应该崩溃,或者如果崩溃了,它应该是不可见的。我想吃掉每个未处理的异常并假装它没有发生。”这不仅是不可能的,而且它几乎违背了所有良好设计的原则(特别是“快速失败”原则,它当然可以重新解释,但永远不应该完全忽视)。

我只能说这么多。如果您不愿意接受其中任何一个,那么祝您找到可行的替代方案。

I'm still not completely sure I understand the question, but a few things to mention:

  • Application.ThreadException and Application.SetUnhandledExceptionMode only apply to Windows Forms threads. Arbitrary ThreadPool threads are not actually Windows Forms threads, even in a Winforms app, so those two lines of code are ineffective.

  • Registering an event with AppDomain.CurrentDomain.UnhandledException will trap exceptions occurring on ThreadPool threads.

  • However, the UnhandledException event cannot actually handle an exception. By that time it's too late to stop the process from terminating, which will always happen if an exception occurs on a background thread (unless you've enabled the legacy .NET 1.1 behavior, but... don't.) This event is really only good for logging or cleanup.

I've tested this myself using test code similar to yours and verified that the code inside the exception "handler" does execute. But the app will still crash, and you can't stop it.

Update: I'm going to make one more attempt at this, and that's it.

If your aim is to have an unattended application running at all times, you have precisely three options:

  1. Handle your exceptions properly. This is, by far, the best and probably only correct solution. Hooking AppDomain.UnhandledException is not handling the exception. By the time control enters that event handler, your application has already crashed. You can't save it anymore.

    An unhandled exception escaping from a background thread is a catastrophic bug in your code that you need to fix. An unhandled exception escaping from a background thread is a catastrophic bug in your code that you need to fix. An unhandled exception escaping from a background thread is a catastrophic bug in your code that you need to fix. Please, no more comments to the effect of "I don't care" - you need to start caring.

  2. Ask Windows politely to restart the application for you. Unlike attempting the restart from a crash handler, which is an incredibly bad idea for reasons too numerous to fully enumerate (data corruption, infinite restart loops, resource leaks, OS instability, etc.), registering for a restart actually allows this to happen in a semi-controlled fashion. As I mentioned in the comments, it's straightforward to interop with this API in .NET. You register for this as soon as the application starts, not when it crashes and your app is in an untrusted state.

  3. Create a supervisor service that watches your application and restarts it if it crashes. This is still bad for many of the reasons discussed in the previous two points, but you at least have a fighting chance at some level of stability.

    You can get a pretty reliable indication of an application crash by using a named mutex, waiting on that in your supervisor, and watching for the WAIT_ABANDONED state (AbandonedMutexException in .NET). The abandoned state only occurs when the process that owns a mutex terminates without releasing it - i.e. has an unhandled exception. And with a little bit more interop hacking, you can also detect and close the crash window.

Those are your options. I strongly suggest that you handle exceptions on background threads, because an unhandled exception escaping from a background thread is a catastrophic bug in your code that you need to fix. If it's coming from an external component and you can't catch it, then the catastrophic bug is in that component and you should consider reporting it to the author or using a different component.

Simply having a requirement that says "this application must run at all times and should totally ignore fatal crashes" doesn't make that scenario possible if the app isn't stable enough to actually keep running. A crash is a crash. You don't design a car to just restart itself immediately if the engine suddenly dies. The best you can do is ask a trusted operator, whether that's a human operator, operating system or some supervisory software - to restart the application on its behalf.

Variations of this question seem to come up so often - basically, "My app should never crash, or if it does, it should be invisible. I want to eat every unhandled exception and pretend it didn't happen." Not only is that impossible but it runs counter to virtually every principle of good design (especially the "fail fast" principle, which can certainly be re-interpreted but should never be ignored entirely).

That's all I can say. If you're unwilling to accept any of it then good luck finding a viable alternative.

狼性发作 2024-09-09 18:03:44

Visual Studio 可能会设置为在发生异常时中断,但如果您继续单步调试代码,它仍应遵循您想要的路径。您还应该尝试在 VS 之外运行该应用程序。

在未处理的异常之后重新启动应用程序是一个坏主意,因为您(根据定义)处于未知状态。如果异常条件从未改变,重新启动(即使可能)可能会让您陷入永无休止的重新启动循环。相反,请考虑尝试将异常信息记录到 Web 服务器,以便您可以调查并修复崩溃。不过,在上传崩溃数据之前,请务必获得用户的许可。

Visual Studio may be set to break on exceptions, but if you continue stepping through the code, it should still follow your desired path. You should also try running the app outside of VS.

Restarting the application after an unhandled exception is a bad idea because you're (by definition) in an unknown state. Restarting, if even possible, may put you in a never-ending loop of restarting if the exception condition is never changed. Instead, consider trying to log the exception information to a web server so you can investigate and fix crashes. Be sure to get the user's permission before uploading the crash data though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文