亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時間:2019年05月06日 11:27:14   作者:行走即歌  
這篇文章主要介紹了C#多線程中的異常處理操作,涉及C#多線程及異常的捕獲、處理等相關(guān)操作技巧,需要的朋友可以參考下

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

常規(guī)Thread中處理異常

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

static void Main(string[] args)
{
  ThreadStart threadStart = DoWork;
  Thread thread = new Thread(threadStart);
  thread.Start();
  thread.Join();
}
static void DoWork()
{
  try
  {
    throw new Exception("子線程出現(xiàn)異常了");
  }
  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 是并行任務(wù)中捕獲的一組異常

通過延續(xù)任務(wù)捕獲前驅(qū)任務(wù)中的異常

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

前驅(qū)任務(wù):使用Run書寫的第一個任務(wù)就是前驅(qū)任務(wù)

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

TaskContinuationOptions:指定延續(xù)任務(wù)時的可配置項(xiàng),默認(rèn)情況下前驅(qū)任務(wù)完成后,立即執(zhí)行延續(xù)任務(wù),OnlyOnFaulted表示只有前驅(qū)任務(wù)失敗(出異常的時候)才會執(zhí)行這一個延續(xù)任務(wù)

Task.Exception也是一個AggregateException 異常

注意:

1.當(dāng)指定的TaskContinuationOptions與前驅(qū)任務(wù)運(yùn)行結(jié)果不一致時,強(qiáng)制調(diào)用延續(xù)任務(wù)Wait()會引發(fā)TaskCanceledException異常

static void Main(string[] args)
{
  Task task = new Task(() =>
  {
    Console.WriteLine("前驅(qū)動任務(wù)執(zhí)行中...");
  });
  Task faultedTask = task.ContinueWith(antecedentTask =>
  {
    Console.WriteLine("延續(xù)動任務(wù)執(zhí)行中...");
  }, 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($"前驅(qū)任務(wù)狀態(tài){task.Status}");
  Console.WriteLine($"延續(xù)任務(wù)狀態(tài){faultedTask.Status}");
}

Ctrl+F5 輸出

補(bǔ)充:

假如在前驅(qū)任務(wù)中出現(xiàn)了異常,如OnlyOnFaulted所愿,會執(zhí)行faultedTask任務(wù),并且在faultedTask.Wait()中不會捕捉到前驅(qū)任務(wù)的異常,具體看下面一點(diǎn)

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

static void Main(string[] args)
{
  Task task = Task.Run(()
    =>
  throw new Exception("前驅(qū)任務(wù)異常了"));
  Task task1 = task.ContinueWith(antecedentTask =>
  {
    throw new Exception("延續(xù)任務(wù)1異常了");
  });
  Task task2 = task1.ContinueWith(antecedentTask =>
  {
    throw new Exception("延續(xù)任務(wù)2異常了");
  });
  Task task3 = task2.ContinueWith(antecedentTask =>
  {
    throw new Exception("延續(xù)任務(wù)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 輸出

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

使用CancellationTokenSource取消任務(wù)

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

Ctrl+F5 輸出

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

小結(jié):

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

更多關(guān)于C#相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《C#常見控件用法教程》、《WinForm控件用法總結(jié)》、《C#數(shù)據(jù)結(jié)構(gòu)與算法教程》、《C#面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》及《C#程序設(shè)計(jì)之線程使用技巧總結(jié)

希望本文所述對大家C#程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • C# TabControl控件中TabPage選項(xiàng)卡切換時的觸發(fā)事件問題

    C# TabControl控件中TabPage選項(xiàng)卡切換時的觸發(fā)事件問題

    這篇文章主要介紹了C# TabControl控件中TabPage選項(xiàng)卡切換時的觸發(fā)事件問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 利用C#快速查出哪些QQ好友空間屏蔽了自己

    利用C#快速查出哪些QQ好友空間屏蔽了自己

    我們經(jīng)常會遇到以下情況吧:想點(diǎn)擊好友空間看看他最近的動態(tài),結(jié)果發(fā)現(xiàn)自己需要申請權(quán)限!別擔(dān)心,本文將為大家介紹如何利用C#快速查出哪些QQ好友空間屏蔽了自己,需要的可以參考一下
    2022-02-02
  • C#隊(duì)列的簡單使用

    C#隊(duì)列的簡單使用

    隊(duì)列的特性很簡答,就是先進(jìn)先出,一般利用數(shù)組來實(shí)現(xiàn),本文就介紹了C#隊(duì)列的簡單使用,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C#泛型Dictionary的用法實(shí)例詳解

    C#泛型Dictionary的用法實(shí)例詳解

    這篇文章主要介紹了C#泛型Dictionary的用法,并以實(shí)例的形式講述了對鍵值對的填充、移除及遍歷等操作,需要的朋友可以參考下
    2014-09-09
  • C#實(shí)現(xiàn)冒泡排序和插入排序算法

    C#實(shí)現(xiàn)冒泡排序和插入排序算法

    這篇文章介紹了C#實(shí)現(xiàn)冒泡排序和插入排序算法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#中執(zhí)行批處理文件(*.bat)的方法代碼

    C#中執(zhí)行批處理文件(*.bat)的方法代碼

    本文介紹一下在C#中執(zhí)行批處理文件(*.bat)的方法。
    2013-03-03
  • C#?Socket數(shù)據(jù)接收的三種實(shí)現(xiàn)方式

    C#?Socket數(shù)據(jù)接收的三種實(shí)現(xiàn)方式

    本文主要介紹了C#?Socket數(shù)據(jù)接收的三種實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • C#實(shí)現(xiàn)二叉查找樹

    C#實(shí)現(xiàn)二叉查找樹

    本文詳細(xì)講解了C#實(shí)現(xiàn)二叉查找樹的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • UnityRTS實(shí)現(xiàn)相機(jī)移動縮放功能

    UnityRTS實(shí)現(xiàn)相機(jī)移動縮放功能

    這篇文章主要為大家詳細(xì)介紹了UnityRTS實(shí)現(xiàn)相機(jī)的移動縮放功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • 詳解C#中SqlParameter的作用與用法

    詳解C#中SqlParameter的作用與用法

    本篇文章主要介紹了C#中SqlParameter的作用與用法,因?yàn)橥ㄟ^SQL語句的方式,有時候存在腳本注入的危險(xiǎn),所以在大多數(shù)情況下不建議用拼接SQL語句字符串方式,希望通過SqlParameter實(shí)現(xiàn)來實(shí)現(xiàn)對數(shù)據(jù)的操作。
    2016-12-12

最新評論