一、C#静态构造函数抛出异常
静态构造函数内部抛出异常时,此异常会被包起来,重新成为一个新的异常抛出,异常信息是“xxx的类型初始值设定项引发异常”,内部的异常则是之前抛出的异常。测试如下:
class Test
{
static Test()
{
throw new System.Exception("静态构造函数抛出异常");
}
}
class Program
{
static void Main(string[] args)
{
try
{
Test test = new Test();
}
catch (System.Exception e)
{
System.Console.WriteLine(e.Message);
System.Console.WriteLine(e.InnerException?.Message);
}
finally
{
System.Console.ReadKey();
}
}
}
输出如下所示:
“Hk.Console.Exception.Test”的类型初始值设定项引发异常。
静态构造函数抛出异常
因此当在静态构造函数内部抛出自定义异常时,是无法直接捕获到自定义异常的,需要从Exception
的InnerException
属性从查找,具体测试代码如下所示:
class MyException : System.Exception
{
public MyException(string message) : base(message)
{
}
public int Code { get; set; }
}
class Test
{
static Test()
{
throw new MyException("静态构造函数抛出异常"){Code = 101};
}
}
class Program
{
static void Main(string[] args)
{
try
{
Test test = new Test();
}
catch (MyException e)
{
//无法捕获到
System.Console.WriteLine($"捕获到自定义异常:{e.Message}");
}
catch (System.Exception e)
{
System.Console.WriteLine(e.Message);
// 会获取到静态构造函数的异常抛出
if (e.InnerException is MyException myException)
{
System.Console.WriteLine(myException.Code);
System.Console.WriteLine(myException.Message);
}
}
finally
{
System.Console.ReadKey();
}
}
}
输出如下所示:
“Hk.Console.Exception.Test”的类型初始值设定项引发异常。
101
静态构造函数抛出异常
二、WPF全局异常
在开发过程中我们一般都用try/catch块来捕获异常,但不是每个异常我们都能捕获,程序总会出现一些意想不到的情况,抛出一些未捕获的异常,这时就要用到全局异常捕获,即在程序的最外层加上捕获未处理异常,以免程序奔溃,影响用户体验。
事件 | 描述 |
---|---|
Application.DispatcherUnhandledException | UI线程的未处理异常捕获 |
AppDomain.UnhandledException | 非UI线程的未处理异常捕获 |
TaskScheduler.UnobservedTaskException | Task内未处理异常捕获 |
private void App_OnStartup(object sender, StartupEventArgs e)
{
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException;
}
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
throw new NotImplementedException();
}
private void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
throw new NotImplementedException();
}
<configuration>
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
</configuration>