C# 防止运行时异常导致程序崩溃的全局错误捕获
我创建了一个在客户端之间发送数据的程序,一旦出现运行时异常,整个程序就会退出 我想为所有运行时异常创建一个全局捕捉器,以便我的程序不会在运行时异常发生时退出。发生异常时,程序退出并打印此消息:C# 防止运行时异常导致程序崩溃的全局错误捕获,c#,exception,server,terminate,C#,Exception,Server,Terminate,我创建了一个在客户端之间发送数据的程序,一旦出现运行时异常,整个程序就会退出 我想为所有运行时异常创建一个全局捕捉器,以便我的程序不会在运行时异常发生时退出。发生异常时,程序退出并打印此消息: Process finished with exit code -532,462,766. 这是我的错误堆栈的缩短视图: Unhandled exception. System.Reflection.TargetInvocationException: Exception has been thrown
Process finished with exit code -532,462,766.
这是我的错误堆栈的缩短视图:
Unhandled exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.IO.InvalidDataException: Found invalid data while decoding.
at Game.Packet.PacketReader.ReadString(Int32 length) in PATH:line 53
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
--- End of stack trace from previous location where exception was thrown ---
...
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
我读了一些关于错误将如何冒泡通过的文章,所以我尝试的第一件事是在program.cs中包装我的主语句,但这也不起作用。我尝试的下一件事是在另一个线程上看到的一个解决方案,它说使用AppDomain.CurrentDomain中的委托,所以我这样做了,但也没有起作用,程序退出。这些代表是:
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) => {
Debug.WriteLine(eventArgs.ToString());
};
AppDomain.CurrentDomain.UnhandledException += (sender, exception) => {
Debug.WriteLine(exception.ToString());
};
我来自Java,程序在运行时出错后没有退出;我不确定c#为什么会出现这种情况,并希望得到提示和/或建议。谢谢大家!
编辑:这是一个控制台应用程序,没有代码。很难想出一个主意,但这可能会对您有所帮助 捕获未处理异常的用法是对以下事件使用处理程序:
AppDomain.CurrentDomain.UnhandledException += OnAppDomainException;
Application.ThreadException += OnThreadException; // WinForms
例如:
static private void OnAppDomainException(object sender, UnhandledExceptionEventArgs args)
{
if ( args.ExceptionObject == null ) return;
Handle(sender, (Exception)args.ExceptionObject);
}
static private void OnThreadException(object sender, ThreadExceptionEventArgs args)
{
if ( args.Exception == null ) return;
Handle(sender, args.Exception);
}
具有:
static private void Handle(object sender, Exception ex)
{
try
{
Debug.WriteLine(ex.Message);
}
catch
{
}
Console.WriteLine(ex.Message);
// Or MessageBox.Show(ex.Message);
}
您还可以显示一些高级信息,如堆栈和内部异常链、源代码文件和行号,以及询问用户在使用GUI时如何使用表单(继续或终止)
我从未使用过FirstChanceException
,文档说明它不是用来管理异常的
请注意,在控制台应用程序中,执行是从Main
方法的开始到结束,并且没有应用程序
事件池管理器和调度程序循环保持程序运行,直到触发退出
因此,如果发生异常,进程将退出,除非您有一个循环在发生异常时进行重试,例如,或任何保持程序运行的操作
因此,对于控制台应用程序,您可以拥有一个带有循环的文本主菜单,直到用户选择退出为止,每个操作都有一个try catch finally
,以确保用户在与菜单操作关联的所选方法发生异常时返回菜单
否则,一旦捕获到AppDomain
异常,您就可以记录并显示它,但该过程在任何情况下都会终止,您什么也不能做:这是正常的,因为现在您已退出Main
方法,这就是结束
基本上你可以做这样的事情:
static public void Main(string[] args)
{
try
{
Test();
}
catch (Exception ex)
{
try
{
Debug.WriteLine(ex.Message);
}
catch
{
}
Console.WriteLine(ex.Message);
Console.WriteLine("Restart?");
if ( Console.ReadLine() == "yes" )
Main(args);
}
}
static void Test()
{
throw new Exception("test error");
}
使用调试堆栈中的高级信息,您可以:
test error
Type: System.Exception
Module: ConsoleApp.exe
Thread: Main
File: Program.cs
Method: ConsoleApp.Program.Test
Line: 73
Restart?
no
请共享主程序代码和项目类型(控制台应用程序?web应用程序?)。捕获的异常不会使程序退出。@AthanasiosKataras这发生在控制台应用程序中!main语句只是初始化所有用于缓存的数据。错误可能发生在任何地方,我需要一种更通用的方法来捕获所有未处理的异常,以便可以返回处理它们。谢谢您无法处理意外异常。您的程序状态不再为人所知,执行无法以任何安全方式进行。最接近您的目标是将
try
/catch
放在每个线程的顶部,但是有些异常根本无法捕获,甚至那些您仍然可以留下损坏状态问题的异常。您好!我一直在读你的帖子,试图消化这些信息。你的回答很好。目前,我对web应用程序和控制台应用程序都有这个问题,但是由于套接字侦听,这两个应用程序都是持久化应用程序。我所做的是使用main初始化可能需要的任何数据并创建套接字。我的服务器读取传入的数据包,处理它们并发送响应。所以我不确定在哪里使用for循环。我提到的“循环”是WinForms应用程序内部行为,在使用Application.Run()
时运行主窗体。这不是你的。WPF或任何其他GUI也是如此。我谈到这一点是为了解释,在控制台中,Main
中没有启动和直接结束的东西,除非在完成所有非交互操作时,您执行类似于循环的操作以将用户保留在程序中。