避免在C#/.NET中出现“程序停止工作”的情况

35

我有一个用C#/.NET编写的控制台应用程序,我想从一个脚本(nant)中运行它。如果控制台应用程序发生异常,我希望nant可以继续运行,但在Windows Vista中会弹出一个搜索解决方案并要求调试等的窗口。

我想避免在控制台应用程序发生异常时出现“程序停止工作”的弹窗。如何从C#/.NET控制此问题?

(一个类似的问题涉及C语言的问题,但我需要一个适用于C#/.NET的解决方案。)

(澄清一下:我希望将异常传递给nant,但不要弹出弹窗。)

6个回答

46
当出现未处理的异常时,JIT调试器弹出窗口。也就是说,异常一直传递到运行时中任何线程的根部。
为了避免这种情况,您可以处理AppDomain.CurrentDomain.UnhandledException事件,并调用Environment.Exit(1)以优雅地退出。
这将处理应用程序域中所有线程上的所有异常。除非您正在执行任何特殊操作,否则将其放在public static void Main方法中应该就足够了。
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
    Console.Error.WriteLine("Unhandled exception: " + args.ExceptionObject);
    Environment.Exit(1);
};

在这种情况下,您可能应该使用NAnt记录器来写出错误(虽然我无法立即回忆起其API)。

您还可以在计算机上禁用JIT调试。 我只建议在某些情况下这样做,例如对于专用的构建服务器。


1
在执行之前,你应该先询问是否处于发布模式,否则会终止调试。 - Andreas
为什么 args.ExceptionObject 不是 Exception 类型?强制转换安全吗? - Winter
@Winter 很好的问题。我会使用 as 强制转换并自己检查 null - Drew Noakes

2
在Windows Vista中,您可以禁用此对话框以针对您的程序。禁用“问题报告和解决方案功能”。您可以在控制面板中找到它 - >问题报告和解决方案 - >更改设置 - >高级设置 - >关闭我的程序的问题报告。

是的,如果我在自己的机器上设置它,那可能可以,但我希望它被整合到程序中,以便它在其他机器上也能一致地工作。(请参见已接受的答案。) - Ole Lynge
2
我可以在Windows 10上做这个吗? - zsf222

1

只需捕获异常并记录/忽略它即可。


是的,这样可以避免弹出窗口,但也会避免其他调用此程序的程序知道发生了某些异常的优势。请参见已接受的答案。 - Ole Lynge
您可以在 catch 块中调用 Environment.Exit。 - maciejkow

1

弹出窗口是由于未处理的异常而出现的。为了避免这种情况,请确保您的主方法捕获所有异常并将它们转换为其他有用的信息,以便您可以获取它们。仅仅忽略异常是不推荐的。

顺便提一下,记住异常是针对每个线程的,因此如果您的应用程序生成线程或使用线程池线程,则还需要为这些线程设置处理程序。


0
通常这种情况发生在您的应用程序没有处理异常时。如果您将整个控制台应用程序包装在try/catch块中,并只返回一个失败代码,那么您就可以避免这种情况。

0
有时候,如果你使用 System.Timers.Timer,一个 Windows 应用程序会停止工作。
为了解决这个问题,请将 System.Timers.Timer 更改为 System.Windows.Forms.Timer。
祝好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接