AggregateException

#region 集合异常  AggregateException  用于对付 Task 上的异常
/*
 * 在同步调用中可以将方法 包装到 try 然后用 catch 捕获异常,但是异步调用却不能用 try  包装Start()调用来捕获异常,
 * 为什么呢?因为异步调用肯定是会牵扯到其他的方法或线程,这时他会跳出 try catch  
 * 如果是在 try  外面出现的异常呢?emm . 这个时候估计他就用不上了,所以就有了 AggregateException 类来背锅了。
 * 只要这个时候抛出异常了,AggregateException 就将异常信息收集 到catch中
 * 可能有很多个。。。
 * 
 * 说明书上的解释,异步之所以不能用 try catch 捕捉异常,是因为不能用 try块来包装 start()
 * 调用来捕捉异常,因为控制会立即从调用返回,然后控制会离开try 块,而这时距离工作者线程发生异常可能还有好久呢?
 * 一个解决方案是将任务的委托主体包装到 try 块中,引发并被工作者线程捕捉的异常不会造成问题,
 * 因为try 块在工作者线程尚能正常地工作。但未处理的异常就麻烦了,工作者线程不捕获他们.从CLR 2.0 k开始,
 * 任何线程上的未处理异常都会被视为严重错误并造成程序异常终止。所有线程上的所有
 * 异常都必须被捕捉,否则不允许程序运行(嗯,这个好)(要处理未处理异常的高级技术,请参见 高级主题 : 
 * 处理 Thread 上的未处理异常),异步任务中的未处理异常有所不同,在这种情况下,任
 * 务调度会用 " catcall" 异常处理程序来包装委托。如果任务引发未处理的异常,catchall 处理程序来包装委托,
 * 如果任务引发了未处理的异常,catchall 处理程序会捕捉并记录异常细节,防止CLR自动终止进程
 */

//举个栗子

public class Program
{
    public static void Main()
    {
        Task task = Task.Run(() =>
        {
            throw new InvalidOperationException(); // 当对象当前状态的方法调用无效时引发的异常。  抛出异常
            //由于对象的当前状态,操作无效。
        });
        try
        {
            task.Wait();
        }                                   // AggregateException 表示在应用程序执行期间发生的一个或多个错误。
        catch (AggregateException Exception)//  Exception 表示在应用程序执行期间发生的错误。
        {
            Exception.Handle(eachException =>
            {  
                //eachException 是一个参数。  为每个异常执行的谓词。谓词接受系统作为参数。要处理的异常,并返回一个布尔值,以指示是否处理了异常。

                //Console.WriteLine($"ERROR:{ eachException.Source}");//返回当前项目(应用程序)名称

                //Console.WriteLine($"ERROR:{ eachException.Message}");// Message  获取描述当前异常的消息。

                //Console.WriteLine($"ERROR:{ eachException.StackTrace}");//获取调用堆栈上立即帧的字符串表示形式。 其中显示的行数 就是错误代码行数

                //Console.WriteLine($"ERROR:{eachException.InnerException}");//获取当前异常的异常实例

                //Console.WriteLine($"ERROR:{eachException.Data}");//  获取提供附加用户定义信息的键/值对集合的例外。 ??????

                //Console.WriteLine($"ERROR:{eachException.HResult}");//返回 分配给特定值的编码数值异常。

                //Console.WriteLine($"ERROR:{eachException.ToString()}");//获取当前异常消息,并返回堆栈上的错误信息

                //Console.WriteLine($"ERROR:{eachException.GetType()}");//获取当前实例的运行时类型。  返回错误类型

                //Console.WriteLine($"ERROR:{eachException.HelpLink}");//获取或设置与此异常关联的帮助文件的链接。 

                //Console.WriteLine($"ERROR:{eachException.TargetSite}");// 获取引发当前异常的方法。

                //Console.WriteLine($"ERROR:{eachException.Equals("System.InvalidOperationException")}");//确定指定的对象是否等于当前对象。

                //Console.WriteLine($"ERROR:{eachException.GetHashCode()}");//作为默认的哈希函数。

                //Console.WriteLine($"ERROR:{eachException.GetObjectData()}"); // 额。。。 SerializationInfo 存储序列化或反序列化对象所需的所有数据。该类不能继承。
                //参考资料:https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.iserializable.getobjectdata?redirectedfrom=MSDN&view=netframework-4.8#System_Runtime_Serialization_ISerializable_GetObjectData_System_Runtime_Serialization_SerializationInfo_System_Runtime_Serialization_StreamingContext_

                //Console.WriteLine($"ERROR:{eachException.GetBaseException()}");//在派生类重写中返回一个或者多个异常的原因,StackTrace 区别在哪里呢?

                return true;
            });
        }
    }
}

#endregion

你可能感兴趣的:(AggregateException)