自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

.NET 4并行編程入門之Task的休眠

開發(fā) 后端
本文將介紹的是Task的休眠,這也是本.NET 4并行編程系列文章的第四篇。通過休眠,可以起到提高利用效率的作用。

查看本系列其他文章,請參看

[[11751]]

本篇的議題如下:

1.Task的休眠。

1. Task的休眠

有時候,我們常常希望一個Task在等待一段時間之后再運行,也就有點類似之前多線程編程中的Sleep。我們可以設置一個Task休眠多長時間,當這個時間過了,Task就自動的喚醒接著運行。

下面就講講休眠的方法:

a.使用CancellationToken的Wait Handle:

a)  在.NET 4并行編程中,讓一個Task休眠的最好的方式就是使用CancellationToken的等待操作(Wait Handle)。而且操作起來也很簡單:首先創(chuàng)建一個CancellationTokenSource的實例,然后通過這個實例的Token屬性得到一個CancellationToken的實例,然后在用CancellationToken的WaitHandle屬性,然后調用這個這個屬性的WaitOne()方法。其實在之前講述”Task的取消”一文中就已經(jīng)使用過。

b)  WaitOne()方法有很多的重載方法來提供更多的功能,例如可以傳入一個int的整數(shù),表明要休眠多長的時間,單位是微秒,也可以傳入一個TimeSpan的值。如果調用了CancellationToken的Cancel()方法,那么休眠就立刻結束。就是因為這個原因,我們之前的文章講過,WaitOne()可以作為檢測Task是否被取消的一個方案

下面來看一段示例代碼:

代碼 
 

  1. static void Main(string[] args)  
  2. {  
  3.     // create the cancellation token source  
  4.     CancellationTokenSource tokenSource = new CancellationTokenSource();  
  5.  
  6.     // create the cancellation token  
  7.     CancellationToken token = tokenSource.Token;  
  8.  
  9.     // create the first task, which we will let run fully  
  10.     Task task1 = new Task(() =>  
  11.     {  
  12.  for (int i = 0; i < Int32.MaxValue; i++)  
  13.  {  
  14.      // put the task to sleep for 10 seconds  
  15.      bool cancelled = token.WaitHandle.WaitOne(10000);  
  16.      // print out a message  
  17.      Console.WriteLine("Task 1 - Int value {0}. Cancelled? {1}",  
  18.      i, cancelled);  
  19.      // check to see if we have been cancelled  
  20.      if (cancelled)  
  21.      {  
  22.   throw new OperationCanceledException(token);  
  23.      }  
  24.  }  
  25.     }, token);  
  26.     // start task  
  27.     task1.Start();  
  28.  
  29.     // wait for input before exiting  
  30.     Console.WriteLine("Press enter to cancel token.");  
  31.     Console.ReadLine();  
  32.  
  33.     // cancel the token  
  34.     tokenSource.Cancel();  
  35.  
  36.     // wait for input before exiting  
  37.     Console.WriteLine("Main method complete. Press enter to finish.");  
  38.     Console.ReadLine();  

 

在上面的代碼中,task在休眠了10秒鐘之后就打印出一條信息。在例子中,在我們敲一下鍵盤之后,CancellationToken就會被Cancel,此時休眠就停止了,task重新喚醒,只不過是這個task將會被cancel掉。

有一點要注意:WaitOne()方法只有在設定的時間間隔到了,或者Cancel方法被調用,此時task才會被喚醒。如果如果cancel()方法被調用而導致task被喚醒,那么CancellationToken.WaitHandle.WaitOne()方法就會返回true,如果是因為設定的時間到了而導致task喚醒,那么CancellationToken.WaitHandle.WaitOne()方法返回false。

b.task休眠的第二種方法:使用傳統(tǒng)的Sleep。

我們現(xiàn)在已經(jīng)知道了:其實TPL(并行編程)的底層還是基于.NET的線程機制的。所以還是可以用傳統(tǒng)的線程技術來使得一個task休眠:調用靜態(tài)方法—Thread.Sleep(),并且可以傳入一個int類型的參數(shù),表示要休眠多長時間。

代碼 

  1. static void Main(string[] args)  
  2.  {  
  3.      // create the cancellation token source  
  4.      CancellationTokenSource tokenSource = new CancellationTokenSource();  
  5.  
  6.      // create the cancellation token  
  7.      CancellationToken token = tokenSource.Token;  
  8.  
  9.      // create the first task, which we will let run fully  
  10.      Task task1 = new Task(() =>  
  11.      {  
  12.   for (int i = 0; i < Int32.MaxValue; i++)  
  13.   {  
  14.       // put the task to sleep for 10 seconds  
  15.       Thread.Sleep(10000);  
  16.  
  17.       // print out a message  
  18.       Console.WriteLine("Task 1 - Int value {0}", i);  
  19.       // check for task cancellation  
  20.       token.ThrowIfCancellationRequested();  
  21.   }  
  22.      }, token);  
  23.      // start task  
  24.      task1.Start();  
  25.  
  26.      // wait for input before exiting  
  27.      Console.WriteLine("Press enter to cancel token.");  
  28.      Console.ReadLine();  
  29.  
  30.      // cancel the token  
  31.      tokenSource.Cancel();  
  32.  
  33.      // wait for input before exiting  
  34.      Console.WriteLine("Main method complete. Press enter to finish.");  
  35.      Console.ReadLine();  
  36.  } 

這種方法和之前第一種方法最大的區(qū)別就是:使用Thread.Sleep()之后,然后再調用token的cancel方法,task不會立即就被cancel,這主要是因為Thread.Sleep()將會一直阻塞線程,直到達到了設定的時間,這之后,再去check task時候被cancel了。舉個例子,假設再task方法體內調用Thread.Sleep(100000)方法來休眠task,然后再后面的代碼中調用token.Cancel()方法,此時處于并行編程內部機制不會去檢測task是否已經(jīng)發(fā)出了cancel請求,而是一直休眠,直到時間超過了100000微秒。如果采用的是之前的第一種休眠方法,那么不管WaitOne()中設置了多長的時間,只要token.Cancel()被調用,那么task就像內部的Scheduler發(fā)出了cancel的請求,而且task會被cancel。

c.第三種休眠方法:自旋等待.

這種方法也是值得推薦的。之前的兩種方法,當他們使得task休眠的時候,這些task已經(jīng)從Scheduler的管理中退出來了,不被再內部的Scheduler管理(Scheduler,這里只是簡單的提下,因為后面的文章會詳細講述,這里只要知道Scheduler是負責管理線程的),因為休眠的task已經(jīng)不被Scheduler管理了,所以Scheduler必須做一些工作去決定下一步是哪個線程要運行,并且啟動它。為了避免Scheduler做那些工作,我們可以采用自旋等待:此時這個休眠的task所對應的線程不會從Scheduler中退出,這個task會把自己和CPU的輪轉關聯(lián)起來,我們還是用代碼示例講解吧。

代碼 

  1. static void Main(string[] args)  
  2.  {  
  3.      // create the cancellation token source  
  4.      CancellationTokenSource tokenSource = new CancellationTokenSource();  
  5.  
  6.      // create the cancellation token  
  7.      CancellationToken token = tokenSource.Token;  
  8.  
  9.      // create the first task, which we will let run fully  
  10.      Task task1 = new Task(() =>  
  11.      {  
  12.   for (int i = 0; i < Int32.MaxValue; i++)  
  13.   {  
  14.       // put the task to sleep for 10 seconds  
  15.       Thread.SpinWait(10000);  
  16.       // print out a message  
  17.       Console.WriteLine("Task 1 - Int value {0}", i);  
  18.       // check for task cancellation  
  19.       token.ThrowIfCancellationRequested();  
  20.   }  
  21.      }, token);  
  22.  
  23.      // start task  
  24.      task1.Start();  
  25.  
  26.      // wait for input before exiting  
  27.      Console.WriteLine("Press enter to cancel token.");  
  28.  
  29.      Console.ReadLine();  
  30.      // cancel the token  
  31.      tokenSource.Cancel();  
  32.  
  33.      // wait for input before exiting  
  34.      Console.WriteLine("Main method complete. Press enter to finish.");  
  35.      Console.ReadLine();  
  36.  } 

代碼中我們在Thread.SpinWait()方法中傳入一個整數(shù),這個整數(shù)就表示CPU時間片輪轉的次數(shù),至于要等待多長的時間,這個就和計算機有關了,不同的計算機,CPU的輪轉時間不一樣。自旋等待的方法常常于獲得同步鎖,后續(xù)會講解。使用自旋等待會一直占用CPU,而且也會消耗CPU的資源,更大的問題就是這個方法會影響Scheduler的運作。

今天就寫道這里:后續(xù)文章將會逐一講解:Task的等待完成操作,Task中的異常處理,獲取Task的狀態(tài),執(zhí)行Lazily Task,常見問題解決方案。

原文標題:.NET 4 并行(多核)編程系列之四

鏈接:http://www.cnblogs.com/Leo_wl/archive/2010/06/01/1749597.html

【編輯推薦】

  1. 微軟發(fā)布新版Windows 7及.NET 4軟件開發(fā)工具包
  2. 詳解.NET 4.0并行計算支持歷史
  3. 詳讀.NET 4.0環(huán)境配置
  4. 詳解.NET 4.0中異常處理方面的新特性
  5. 三方面詮釋.NET 4.0的新特性

 

 

責任編輯:彭凡 來源: 博客園
相關推薦

2010-06-04 09:11:10

.NET并行編程

2010-06-07 08:43:46

.NET 4并行編程

2010-06-09 09:18:34

.NET 4并行編程

2010-06-02 08:53:51

.NET 4并行編程

2010-06-11 09:01:02

.NET 4并行編程

2011-03-24 09:23:43

.NET 4多核并行

2010-06-24 09:12:27

.NET 4并行編程

2015-10-13 09:18:00

.Net編程教程

2024-09-29 16:22:18

多線程TaskC#

2024-09-27 19:42:09

工具C#Task?

2024-04-07 09:04:18

Parallel 類編程工具.NET

2024-06-04 15:56:48

Task?.NET異步編程

2009-07-24 15:41:00

ASP.NET編程入門

2010-04-21 09:23:09

.NET 4

2017-04-25 15:20:11

Python進程mpi4py

2011-07-11 09:29:32

PHP面向對象編程

2012-04-10 10:04:26

并行編程

2009-02-23 15:20:03

SQL Server數(shù)據(jù)庫ASP.NET

2023-10-30 08:57:19

.Net開發(fā)并行計算

2012-04-06 10:31:44

Java
點贊
收藏

51CTO技術棧公眾號