转 C#WinForm程序异常退出的捕获继续执行与自动重启

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转 C#WinForm程序异常退出的捕获继续执行与自动重启相关的知识,希望对你有一定的参考价值。

特别声明:本文是转载的,在这里向原作者表示深深的感谢!解决我们的一个大问题!

本文参考网上搜索的信息,并做了适当修改可以让捕捉到异常之后阻止程序退出。

另给出了通过命令行自动重启的方法。

如果一个线程里运行下面的代码

            int a = 0;
            int c = 10 / a;

将会导致程序自动结束,而且没有任何提示信息 但是如果是在主线程里运行这个代码,是会弹出异常信息对话框的

请问如何在线程里也出现这个异常信息对话框.或者避免程序直接退出,忽略异常,继续往下执行呢?
 
在WINFORM主线程捕获全部异常就行,如下代码:
            //处理未捕获的异常
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
            //处理UI线程异常
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            //处理非UI线程异常
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
 最常出现的错误在 :UnhandledException 里出现。详细代码如下:
技术分享
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] args) 
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            //处理未捕获的异常
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
            //处理UI线程异常
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            //处理非UI线程异常
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

            Application.Run(new Form1(args));
            glExitApp = true;//标志应用程序可以退出
        }

        /// <summary>
        /// 是否退出应用程序
        /// </summary>
        static bool glExitApp = false;

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            LogHelper.Save("CurrentDomain_UnhandledException", LogType.Error);
            LogHelper.Save("IsTerminating : " + e.IsTerminating.ToString(), LogType.Error);
            LogHelper.Save(e.ExceptionObject.ToString());

            while (true)
            {//循环处理,否则应用程序将会退出
                if (glExitApp) {//标志应用程序可以退出,否则程序退出后,进程仍然在运行
                    LogHelper.Save("ExitApp");
                    return; 
                }
                System.Threading.Thread.Sleep(2*1000);
            };
        }
        
        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            LogHelper.Save("Application_ThreadException:" +
                e.Exception.Message, LogType.Error);
            LogHelper.Save(e.Exception);
            //throw new NotImplementedException();
        }
技术分享

 如果程序需要重启只需要在捕获的事件处理时启动当前应用程序的代码即可。参考如下:

技术分享
CmdStartCTIProc(Application.ExecutablePath, "cmd params");//放到捕获事件的处理代码后,重启程序,需要时加上重启的参数


        /// <summary>
        /// 在命令行窗口中执行
        /// </summary>
        /// <param name="sExePath"></param>
        /// <param name="sArguments"></param>
        static void CmdStartCTIProc(string sExePath, string sArguments)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = false;
            p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            p.Start();
            p.StandardInput.WriteLine(sExePath + " " + sArguments);
            p.StandardInput.WriteLine("exit");
            p.Close();

            System.Threading.Thread.Sleep(2000);//必须等待,否则重启的程序还未启动完成;根据情况调整等待时间
        }
技术分享

 另外一种重启进程的方式:

            //重启程序,需要时加上重启的参数
            System.Diagnostics.ProcessStartInfo cp = new System.Diagnostics.ProcessStartInfo();
            cp.FileName = Application.ExecutablePath;
            cp.Arguments = "cmd params";
            cp.UseShellExecute = true;
            System.Diagnostics.Process.Start(cp);

以上是关于转 C#WinForm程序异常退出的捕获继续执行与自动重启的主要内容,如果未能解决你的问题,请参考以下文章

winform程序捕获全局异常,对错误信息写入日志并弹窗

为啥我的 Java 程序在捕获到异常后退出?

20172322 2017-2018-2 《程序设计与数据结构》第九周学习总结

Python 3 基础之异常及其捕获

java捕获到异常后,异常后的语句不会被执行

全套异常捕获与处理