异常处理 的相关注意事项

本例描述几个常用的异常处理,及可能出现的问题:

finally的相关使用

嵌套异常

捕获多线程的异常[使用事件通知的方式,将异常包装到主线程中]

using System; 
using System.Threading.Tasks;

namespace ConsoleApp_HandleException
{
class Program
{
static void Main(string[] args)
{
//TestInvoke();

//MethodWithTryNesting();
//Console.WriteLine();
//MethodWithTry();

TryCatchMultiThreadException2();

Console.ReadKey();
}

#region finally的相关使用

static void TestInvoke()
{
int result1 = TestIntReturnBelowFinally();
int result2 = TestIntReturnInTry();
User result3 = TestUserReturnInTry();

Console.ReadKey();
}

static int TestIntReturnBelowFinally()
{
int i;
try
{
i = 1;
}
finally
{
i = 2;
Console.WriteLine(" 将int结果改为2,finally执行完毕!");
}
return i;//执行顺序:try,finally,return i为2,返回2
}

static int TestIntReturnInTry()
{
int i;
try
{
return i = 1;//执行顺序:i=1,finally,return 返回值为1,i=2(在finally中的修改,未能影响到返回值)
}
finally
{
i = 2;
Console.WriteLine(" 将int结果改为2,finally执行完毕!");
}
}

//返回名称为Li si
static User TestUserReturnInTry()
{
User user = new User() { Name = "Zhang san" };
try
{
return user;//执行顺序:try,finally,return 返回名称为Li si(在finally中的修改,(由于是引用类型,所以)影响到了返回值)
}
finally
{
user.Name = "Li si";
Console.WriteLine(" 将user.Name改为 Li si !");
user = null;//返回值的名称为Li si,因为2个引用指向同一个内存,只是将其中一个引用置空了
}
}

class User
{
public string Name;
}
#endregion

#region 捕获异常

/* 避免使用:
* catch (Exception err)
* {
* throw err;
* }
*
* 改用:
* catch //(Exception) //可以返回出错的位置
* {
* throw;
* }
*
* 外界再次捕获异常时,无法找到原始出错的位置,堆栈被重置了 (只能显示MethodWithTry方法中的catch位置)
*
*/

/// <summary>
/// 嵌套异常
/// </summary>
static void MethodWithTryNesting()
{
try
{
MethodWithTry();
}
catch (Exception error1)
{
Console.WriteLine(error1.StackTrace);
}
}

static void MethodWithTry()
{
try
{
Method1();
}
//catch (Exception err)//外界再次捕获异常时,无法找到原始出错的位置,堆栈被重置了 (只能显示MethodWithTry方法中的catch位置)
//{
// throw err;
//}
catch //(Exception) //可以返回出错的位置
{
throw;
}
}

static int Method1()
{
int i = 0;
return 10 / i;
}

#endregion

#region 捕获多线程的异常[在Windows应用程序中]

//public void TryCatchMultiThreadException()
//{
// Thread t=new Thread((ThreadStart) delegate
// {
// try
// {
// throw new Exception("非UI线程异常");
// }
// catch (Exception ex)
// {
// //将线程内部的异常传递到主线程上
// this.BeginInvoke((Action) delegate
// {
// throw ex;
// });
// }

// });
//}

#endregion

#region 捕获多线程的异常[使用事件通知的方式,将异常包装到主线程中]

private static event EventHandler<AggregateExceptionArgs> AggregateExceptionCatched;

public class AggregateExceptionArgs : EventArgs
{
public AggregateException AggregateException { get; set; }
}

public static void TryCatchMultiThreadException2()
{
AggregateExceptionCatched += Program_AggregateExceptionCatched;

Task t = new Task(() =>
{
try
{
//do something 执行正常代码,产生了异常
throw new InvalidOperationException("任务并行编码中产生的未知异常");
}
catch (Exception err)
{
AggregateExceptionArgs errArgs = new AggregateExceptionArgs()
{
AggregateException = new AggregateException(err)
};
AggregateExceptionCatched(null, errArgs);
}
});
t.Start();

Console.WriteLine("主线程即将结束");
Console.ReadKey();
}

static void Program_AggregateExceptionCatched(object sender, Program.AggregateExceptionArgs e)
{
foreach (var item in e.AggregateException.InnerExceptions)
{
Console.WriteLine("异常类型:{0}{1}来自:{2}{3}异常内容:{4}",
item.GetType(), Environment.NewLine, item.Source, Environment.NewLine, item.Message);
}
}

#endregion
}

}

原文地址:https://www.cnblogs.com/jx270/p/3665006.html