国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#多線程中的異常處理操作示例

2020-01-24 00:05:23
字體:
來源:轉載
供稿:網友

本文實例講述了C#多線程中的異常處理操作。分享給大家供大家參考,具體如下:

常規Thread中處理異常

使用Thread創建的子線程,需要在委托中捕捉,無法在上下文線程中捕捉

static void Main(string[] args){  ThreadStart threadStart = DoWork;  Thread thread = new Thread(threadStart);  thread.Start();  thread.Join();}static void DoWork(){  try  {    throw new Exception("子線程出現異常了");  }  catch (Exception ex)  {    Trace.Assert(false, "Catch In Delegate");  }}

Task中處理異常

1.仍然可以在委托中捕獲異常

2.可以捕獲Task.Wait() 或者 Task.Result 的 AggregateException 異常

try{  task.Wait();}catch (AggregateException ex){  Console.WriteLine($"Error: {ex.GetType().Name}");  foreach (Exception item in ex.InnerExceptions)  {    Console.WriteLine($"{item.GetType().Name}, {item.Message}");  }}

AggregateException 是并行任務中捕獲的一組異常

通過延續任務捕獲前驅任務中的異常

static void Main(string[] args){  Task task = Task.Run(() => throw new Exception("前驅任務異常了"));  Task faultedTask = task.ContinueWith(antecedentTask =>  {    antecedentTask.Exception.Handle(eachE =>    {      Console.WriteLine($"Error: {eachE.Message}");      return true;    });  },TaskContinuationOptions.OnlyOnFaulted);  faultedTask.Wait();}

前驅任務:使用Run書寫的第一個任務就是前驅任務

延續任務:在一個任務后使用ContinueWith添加的任務就是延續任務,延續一般是一個全新的工作線程

TaskContinuationOptions:指定延續任務時的可配置項,默認情況下前驅任務完成后,立即執行延續任務,OnlyOnFaulted表示只有前驅任務失敗(出異常的時候)才會執行這一個延續任務

Task.Exception也是一個AggregateException 異常

注意:

1.當指定的TaskContinuationOptions與前驅任務運行結果不一致時,強制調用延續任務Wait()會引發TaskCanceledException異常

static void Main(string[] args){  Task task = new Task(() =>  {    Console.WriteLine("前驅動任務執行中...");  });  Task faultedTask = task.ContinueWith(antecedentTask =>  {    Console.WriteLine("延續動任務執行中...");  }, TaskContinuationOptions.OnlyOnFaulted);  task.Start();  try  {    faultedTask.Wait();  }  catch (AggregateException ex)  {    Console.WriteLine($"Error: {ex.GetType().Name}");    foreach (Exception item in ex.InnerExceptions)    {      Console.WriteLine($"{item.GetType().Name}, {item.Message}");    }  }  Console.WriteLine($"前驅任務狀態{task.Status}");  Console.WriteLine($"延續任務狀態{faultedTask.Status}");}

Ctrl+F5 輸出

補充:

假如在前驅任務中出現了異常,如OnlyOnFaulted所愿,會執行faultedTask任務,并且在faultedTask.Wait()中不會捕捉到前驅任務的異常,具體看下面一點

2.延續任務雖然在異步任務中提供了類似if else 的ContinueWith但是在異常處理上還是有點局限,看一個例子

static void Main(string[] args){  Task task = Task.Run(()    =>  throw new Exception("前驅任務異常了"));  Task task1 = task.ContinueWith(antecedentTask =>  {    throw new Exception("延續任務1異常了");  });  Task task2 = task1.ContinueWith(antecedentTask =>  {    throw new Exception("延續任務2異常了");  });  Task task3 = task2.ContinueWith(antecedentTask =>  {    throw new Exception("延續任務3異常了");  });  try  {    task3.Wait();  }  catch (AggregateException ex)  {    Console.WriteLine($"Error: {ex.GetType().Name}");    foreach (Exception item in ex.InnerExceptions)    {      Console.WriteLine($"{item.GetType().Name}, {item.Message}");    }  }}

Ctrl+F5 輸出

其實這樣也可以理解,task3.Wait()只會收集task3所在工作線程上的異常,遺憾的是Task.Exception.InnerExceptions是一個只讀集合,這樣一來,每個任務的異常只能在各自委托中處理了,事實上也應該如此,可以使用TaskContinuationOptions進行靈活控制

使用CancellationTokenSource取消任務

static void Main(string[] args){  CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();  cancellationTokenSource.Token.Register(() =>   {    Console.WriteLine("任務取消了");  });  cancellationTokenSource.CancelAfter(2000);  Task task = Task.Run(() =>  {    while (true && !cancellationTokenSource.IsCancellationRequested)    {      Console.WriteLine("任務執行中...");      Thread.Sleep(300);     }  },  cancellationTokenSource.Token);  task.Wait();  Console.WriteLine($"任務的最終狀態是:{task.Status}");}

Ctrl+F5 輸出

正常取消的任務最終狀態是 RanToCompletion ,這里要注意的是,CancelAfter()是在這個方法調用的那一刻開始計時的(并非以Run開始計時,好吧,很好理解,我卻疑惑了半天)

小結:

結合 TaskContinuationOptions 和 CancellationTokenSource 可以很好處理多任務中異常,但是編寫在異步程序還是很繁瑣的,具體的在下一個筆記中會結合C#5.0做一個比較

更多關于C#相關內容感興趣的讀者可查看本站專題:《C#常見控件用法教程》、《WinForm控件用法總結》、《C#數據結構與算法教程》、《C#面向對象程序設計入門教程》及《C#程序設計之線程使用技巧總結

希望本文所述對大家C#程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 伊金霍洛旗| 连平县| 永丰县| 拜城县| 绥棱县| 白城市| 湖州市| 小金县| 正定县| 万安县| 南京市| 本溪| 徐闻县| 乃东县| 漳平市| 兴山县| 响水县| 东乌珠穆沁旗| 抚州市| 铁力市| 绥棱县| 江口县| 长葛市| 侯马市| 永善县| 婺源县| 安宁市| 兴城市| 抚顺县| 五台县| 丽江市| 昌都县| 元阳县| 驻马店市| 平果县| 贵溪市| 息烽县| 亳州市| 腾冲县| 安阳市| 桑日县|