1. 程式人生 > 實用技巧 >C# async非同步方法異常處理

C# async非同步方法異常處理

建議1:在TaskMethod裡進行try-catch處理

建議2:使用 var tasks=Task.When(params);然後 var results=await tasks;

接著使用 tasks.Exception.Flatern()獲取底層異常集合

建議2示例:

        public static void Main(string [] args)
        {
            Task t= AsyncWithException();
            t.Wait();

            Console.WriteLine("Main Ok
"); Console.Read(); } public static async Task AsyncWithException() { var taskList = new List< Task < string >> (); var t1 = TaskMethod_1214("t1", 1); taskList.Add(t1); var t2 = TaskMethod_1214("t2", 2); taskList.Add(t2);
var t3 = TaskMethod_1214("t3", 3); taskList.Add(t3); var tasks = Task.WhenAll(taskList.ToArray()); try { string[] res = await tasks; } catch (Exception ex) { Console.WriteLine("try-catch 只能捕獲第一個異常
"); // try-catch 只能捕獲底層的第一個異常 Console.WriteLine(ex.Message); Console.WriteLine("Flatten方法可以獲取底層的所有異常"); // Flatten方法可以獲取底層的所有異常 var aggregateException = tasks.Exception.Flatten(); foreach(var e in aggregateException.InnerExceptions) { Console.WriteLine(e.Message); } } } public async static Task<string> TaskMethod_1214(string taskName,int seconds) { await Task.Delay(TimeSpan.FromSeconds(seconds)); throw new Exception(taskName + " Boom"); }

執行結果:

如果要應用建議1,分析程式碼結構知道,我們應該在TaskMethod_1214里加上try-catch處理

綜合建議1和建議2程式碼如下:

        public static void Main(string [] args)
        {
            Task t= AsyncWithException();
            t.Wait();

            Console.WriteLine("Main Ok");

            Console.Read();
        }

        public static async Task AsyncWithException()
        {
            var taskList = new List< Task < string >> ();
            var t1 = TaskMethod_1214("t1", 1);
            taskList.Add(t1);
            var t2 = TaskMethod_1214("t2", 2);
            taskList.Add(t2);
            var t3 = TaskMethod_1214("t3", 3);
            taskList.Add(t3);
            var tasks = Task.WhenAll(taskList.ToArray());
            try
            {
                string[] res = await tasks;
            }
            catch (Exception ex)
            {
                Console.WriteLine("try-catch 只能捕獲第一個異常");
                // try-catch 只能捕獲底層的第一個異常
                Console.WriteLine(ex.Message);

                Console.WriteLine("Flatten方法可以獲取底層的所有異常");
                // Flatten方法可以獲取底層的所有異常
                var aggregateException = tasks.Exception.Flatten();
                foreach(var e in aggregateException.InnerExceptions)
                {
                    Console.WriteLine(e.Message);
                }
            }
        }

        public async static Task<string> TaskMethod_1214(string taskName,int seconds)
        {
            try
            {
                await Task.Delay(TimeSpan.FromSeconds(seconds));

                throw new Exception(taskName + " Boom");
            }
            catch(Exception ex)
            {
                // 這裡進行異常處理邏輯,然後返回單元操作結果資訊
                return "code:-1,msg:"+ex.Message;
            }
        }

執行結果: