欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來到入門教程網(wǎng)!

C#教程

當前位置:主頁 > 軟件編程 > C#教程 >

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

來源:本站原創(chuàng)|時間:2020-01-10|欄目:C#教程|點擊: 次

本文實例講述了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 是并行任務中捕獲的一組異常

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

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

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

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

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

Task.Exception也是一個AggregateException 異常

注意:

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

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

Ctrl+F5 輸出

補充:

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

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

static void Main(string[] args)
{
  Task task = Task.Run(()
    =>
  throw new Exception("前驅(qū)任務異常了"));
  Task task1 = task.ContinueWith(antecedentTask =>
  {
    throw new Exception("延續(xù)任務1異常了");
  });
  Task task2 = task1.ContinueWith(antecedentTask =>
  {
    throw new Exception("延續(xù)任務2異常了");
  });
  Task task3 = task2.ContinueWith(antecedentTask =>
  {
    throw new Exception("延續(xù)任務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("任務執(zhí)行中...");
      Thread.Sleep(300); 
    }
  },
  cancellationTokenSource.Token);
  task.Wait();
  Console.WriteLine($"任務的最終狀態(tài)是:{task.Status}");
}

Ctrl+F5 輸出

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

小結:

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

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

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

上一篇:C#中的多線程小試牛刀

欄    目:C#教程

下一篇:C#如何使用Bogus創(chuàng)建模擬數(shù)據(jù)示例代碼

本文標題:C#多線程中的異常處理操作示例

本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/4764.html

網(wǎng)頁制作CMS教程網(wǎng)絡編程軟件編程腳本語言數(shù)據(jù)庫服務器

如果侵犯了您的權利,請與我們聯(lián)系,我們將在24小時內(nèi)進行處理、任何非本站因素導致的法律后果,本站均不負任何責任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權所有