C# async非同步方法異常處理
阿新 • • 發佈:2020-12-15
建議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; } }
執行結果: