写了一个数据库自动同步数据的c#窗体程序,需要程序一直运行下去。
但是发现,对于数据库操作,即使在程序可能会发生异常的所有地方都防止try catch finally语句还是时不时的弹出timeout异常。这个时候就要人介入,点击退出再重启程序。这种方式肯定不行。
后台查了些资料,这样处理的,在Program.cs文件的Main函数里处理应用程序重新启动:
static void Main()
{
//try
//{
// Application.EnableVisualStyles();
// Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new DatabaseSync());
//}
//catch
//{
// Application.Restart();
//}
}
刚开始能够捕获到异常,然后程序确实没有弹出异常,自动重启了。后来又没有效果了,不知道什么原因。
然后再搜资料,发现了一种解决方式,主要是把异常分为两类:Windows窗体线程异常和非窗体线程异常。我觉得这种方式很好,而且把错误写入日志中便于我们发现弹出的异常到底是哪种类型的异常,便于后续改进。
上代码:
public static FileStream fs;
public static StreamWriter sw;
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//try
//{
// Application.EnableVisualStyles();
// Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new DatabaseSync());
//}
//catch
//{
// Application.Restart();
//}
OpentxtFile();
Application.ThreadException += new ThreadExceptionEventHandler(UIThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new DatabaseSync());
}
public static void OpentxtFile()
{
try
{
//打开错误日志文件
string filePath = Assembly.GetExecutingAssembly().Location;
Int32 i = filePath.LastIndexOf("\\");
filePath = filePath.Remove(i);
filePath = filePath + @"\ApplicationLog.txt";
fs = new FileStream(filePath, FileMode.Append);
sw = new StreamWriter(fs);
}
catch
{
sw.Flush();//关闭流
sw.Close();
fs.Close();
return;
}
}
private static void UIThreadException(object sender, ThreadExceptionEventArgs t)
{
try
{
if (sw != null)
{
sw.WriteLine("Windows窗体线程异常 : \n\n" + t.Exception.Message + Environment.NewLine + t.Exception.StackTrace);
}
}
catch
{
if (sw != null)
{
sw.WriteLine("不可恢复的Windows窗体异常,应用程序将退出!");
}
}
finally
{
Application.Restart();
}
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = (Exception)e.ExceptionObject;
if (sw != null)
{
sw.WriteLine("非窗体线程异常 : \n\n" + ex.Message + Environment.NewLine + ex.StackTrace);
}
}
catch
{
if (sw != null)
{
sw.WriteLine("不可恢复的非Windows窗体异常,应用程序将退出!");
}
}
finally
{
Application.Restart();
}
}
后来经过测试,发现程序自动弹出的timeout异常大都属于Windows窗体线程异常。
而且调试的时候发现,可能是由于网络连接不好,会出现线程停止了,没有进行数据处理了类似这样的调试异常。(程序是OK的)
参考资料:http://www.cnblogs.com/luminji/archive/2011/01/05/1926033.html