C#的子线程的异常处理,直接上代码吧。
首先是Thread
,下面这种情况程序会直接抛异常
static void Main(string[] args)
{
try
{
Thread th = new Thread(Th);
th.Start();
}
catch (Exception ex)
{
//此处永远不会被执行
Console.WriteLine("get ex in child thread");
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
static void Th()
{
string s = null;
int a = s.Length;
}
下面在子线程中添加异常捕捉:
static void Main(string[] args)
{
try
{
Thread th = new Thread(Th);
th.Start();
}
catch (Exception ex)
{
//此处永远不会被执行
Console.WriteLine("get ex in child thread");
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
static void Th()
{
try
{
string s = null;
int a = s.Length;
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
执行结果:
综上所述,使用Thread
时,子线程的异常需要在子线程的内部自行处理,主线程无法捕获子线程的异常。
下面来看看使用Task
的情况
static void Main(string[] args)
{
try
{
Task t = Task.Run(() =>
{
string s = null;
int a = s.Length;
});
t.Wait();
}
catch (Exception ex)
{
Console.WriteLine("get ex in child thread");
Console.WriteLine($"the type of Exception is: {ex.GetType().Name}");
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
运行结果:
下面用异步函数的方式:
static async Task Main(string[] args)
{
try
{
await Task.Run( async () =>
{
string s = null;
int a = s.Length;
await Task.Delay(100);
});
}
catch (Exception ex)
{
Console.WriteLine("get ex in child thread");
Console.WriteLine($"the type of Exception is: {ex.GetType().Name}");
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
看看运行结果:
由此可见使用Task和异步函数,可以对异常更加方便的处理,若使用Thread
类创建的线程,则需要在子线程代码中处理异常。
对异常进行合适的处理对于程序的健壮性有很大的好处,更重要的是当出现问题的时候可以快速定位到问题。