Ste*_*ger 189 .net c# vb.net exception-handling console-application
问题:我想在控制台应用程序中为未处理的异常定义一个全局异常处理程序.在asp.net中,可以在global.asax中定义一个,在windows应用程序/服务中,可以定义如下
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyExceptionHandler);
Run Code Online (Sandbox Code Playgroud)
但是,如何为控制台应用程序定义全局异常处理程序?
currentDomain似乎不起作用(.NET 2.0)?
编辑:
唉,愚蠢的错误.
在VB.NET中,需要在currentDomain前添加"AddHandler"关键字,否则在IntelliSense中看不到UnhandledException事件......
这是因为VB.NET和C#编译器对事件处理的处理方式不同.
Han*_*ant 272
不,这是正确的方法.这完全可以正常工作,你可以从中工作:
using System;
class Program {
static void Main(string[] args) {
System.AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
throw new Exception("Kaboom");
}
static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e) {
Console.WriteLine(e.ExceptionObject.ToString());
Console.WriteLine("Press Enter to continue");
Console.ReadLine();
Environment.Exit(1);
}
}
Run Code Online (Sandbox Code Playgroud)
请记住,您无法通过这种方式捕获由抖动生成的类型和文件加载异常.它们发生在Main()方法开始运行之前.捕获这些需要延迟抖动,将危险代码移动到另一个方法并将[MethodImpl(MethodImplOptions.NoInlining)]属性应用于它.
Blu*_*kMN 23
如果你有一个单线程应用程序,你可以在Main函数中使用一个简单的try/catch,但是,这不包括可能在Main函数之外,在其他线程上抛出的异常,例如(如其他线程所述)评论).此代码演示了异常如何导致应用程序终止,即使您尝试在Main中处理它(注意如果按Enter键并允许应用程序在异常发生之前正常退出,程序将如何正常退出,但是如果您让它运行,它终止得非常不幸):
static bool exiting = false;
static void Main(string[] args)
{
try
{
System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
demo.Start();
Console.ReadLine();
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception");
}
}
static void DemoThread()
{
for(int i = 5; i >= 0; i--)
{
Console.Write("24/{0} =", i);
Console.Out.Flush();
Console.WriteLine("{0}", 24 / i);
System.Threading.Thread.Sleep(1000);
if (exiting) return;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在应用程序退出之前接收另一个线程何时抛出异常以执行某些清理的通知,但据我所知,如果您不处理异常,则无法从控制台应用程序强制应用程序继续运行在没有使用一些模糊的兼容性选项的情况下抛出它的线程,使应用程序的行为与.NET 1.x一样.此代码演示了如何通知主线程来自其他线程的异常,但仍然会不愉快地终止:
static bool exiting = false;
static void Main(string[] args)
{
try
{
System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
demo.Start();
Console.ReadLine();
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception");
}
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("Notified of a thread exception... application is terminating.");
}
static void DemoThread()
{
for(int i = 5; i >= 0; i--)
{
Console.Write("24/{0} =", i);
Console.Out.Flush();
Console.WriteLine("{0}", 24 / i);
System.Threading.Thread.Sleep(1000);
if (exiting) return;
}
}
Run Code Online (Sandbox Code Playgroud)
所以在我看来,在控制台应用程序中处理它的最简单方法是确保每个线程在根级别都有一个异常处理程序:
static bool exiting = false;
static void Main(string[] args)
{
try
{
System.Threading.Thread demo = new System.Threading.Thread(DemoThread);
demo.Start();
Console.ReadLine();
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception");
}
}
static void DemoThread()
{
try
{
for (int i = 5; i >= 0; i--)
{
Console.Write("24/{0} =", i);
Console.Out.Flush();
Console.WriteLine("{0}", 24 / i);
System.Threading.Thread.Sleep(1000);
if (exiting) return;
}
}
catch (Exception ex)
{
Console.WriteLine("Caught an exception on the other thread");
}
}
Run Code Online (Sandbox Code Playgroud)
Bla*_*ICE 12
您还需要处理线程中的异常:
static void Main(string[] args) {
Application.ThreadException += MYThreadHandler;
}
private void MYThreadHandler(object sender, Threading.ThreadExceptionEventArgs e)
{
Console.WriteLine(e.Exception.StackTrace);
}
Run Code Online (Sandbox Code Playgroud)
哎呀,抱歉是winforms,对于你在控制台应用程序中使用的任何线程,你必须将它们包含在try/catch块中.遇到未处理异常的后台线程不会导致应用程序结束.