標籤:
特別聲明:本文是轉載的,在這裡向原作者表示深深的感謝!解決我們的一個大問題!
本文參考網上搜尋的資訊,並做了適當修改可以讓捕捉到異常之後阻止程式退出。
另給出了通過命令列自動重啟的方法。
如果一個線程裡運行下面的代碼
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程式異常退出的捕獲、繼續執行與自動重啟