1. 程式人生 > 實用技巧 >C#WinForm程式異常退出的捕獲、繼續執行與自動重啟

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);

看了覺得有用的朋友,如果您方便的話,可以頂一下。謝謝!

程式崩潰後重啟,可以試試下面的方式:

        /// <summary> 
        /// 應用程式的主入口點。 
        /// </summary> 
        [STAThread] 
        static void Main() 
        { 
            Application.ThreadException+=new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 
            Application.EnableVisualStyles(); 
            Application.SetCompatibleTextRenderingDefault(false); 
            Application.Run(new Form1()); 
        } 

        private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) 
        { 
            Application.Restart(); 
        }

出處:https://www.cnblogs.com/zaspring/archive/2013/04/16/3023927.html