C#WinForm程序异常退出的捕获、继续执行与自动重启
本文参考网上搜索的信息,并做了适当修改可以让捕捉到异常之后阻止程序退出。
另给出了通过命令行自动重启的方法。
如果一个线程里运行除以零的计算,如下面的代码
private void button1_Click(object sender, EventArgs e) { System.Threading.Thread t = new System.Threading.Thread(() => { int a = 0; int c = 10 / a; }); t.Start(); }
将会导致程序自动结束,而且没有任何提示信息 但是如果是在主线程里运行这个代码,是会弹出异常信息对话框的
请问如何在线程里也出现这个异常信息对话框.或者避免程序直接退出,忽略异常,继续往下执行呢?
在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(); }
static class Program { private static log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); /// <summary> /// 是否退出应用程序 /// </summary> static bool glExitApp = false; /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { _log.Info("程序启动"); try { //处理未捕获的异常 System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); System.Windows.Forms.Application.ThreadException += Application_ThreadException; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new WebManager()); glExitApp = true; } catch (Exception ex) { _log.Error(ex); } _log.Info("程序关闭"); } private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { _log.Error("CurrentDomain_UnhandledException ==== IsTerminating : " + e.IsTerminating.ToString()); _log.Error("e.ExceptionObject : " + e.ExceptionObject); _log.Error(e); if (e.IsTerminating) { Common.Globalparams.ShowMessageDialog("系统发生错误,请联系系统管理员,程序即将关闭。"); //循环处理,否则应用程序将会退出 if (glExitApp) { //标志应用程序可以退出,否则程序退出后,进程仍然在运行 _log.Error("====ExitApp"); return; } System.Threading.Thread.Sleep(2 * 1000); _log.Error("====UnhandledException While......"); Common.StartupHelper.CmdStartSelf(); } } private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) { var ex = e.Exception; if (ex != null) { _log.Error(ex); } } }
如果程序需要重启只需要在捕获的事件处理时启动当前应用程序的代码即可。参考如下:
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);
完整代码:
public class StartupHelper { /// <summary> /// 在命令行窗口中执行指定程序。(可以包括程序本身) /// </summary> /// <param name="exePath"></param> /// <param name="sArguments"></param> public static void CmdStartApp(string exePath, string sArguments) { System.Diagnostics.Process p = new System.Diagnostics.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(exePath + " " + sArguments); p.StandardInput.WriteLine("exit"); p.Close(); System.Threading.Thread.Sleep(2000);//必须等待,否则重启的程序还未启动完成;根据情况调整等待时间 } /// <summary> /// 启动程序自己(一般程序异常退出时调用) /// </summary> /// <param name="strArguments"></param> public static void CmdStartSelf(string strArguments = "") { //重启程序,需要时加上重启的参数 System.Diagnostics.ProcessStartInfo cp = new System.Diagnostics.ProcessStartInfo(); cp.FileName = System.Windows.Forms.Application.ExecutablePath; cp.Arguments = strArguments; cp.UseShellExecute = true; System.Diagnostics.Process.Start(cp); } }
看了觉得有用的朋友,如果您方便的话,可以顶一下。谢谢!
出处:https://www.cnblogs.com/zaspring/archive/2013/04/16/3023927.html
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/12196722.html
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!
posted on 2020-01-15 14:57 jack_Meng 阅读(1564) 评论(0) 编辑 收藏 举报