成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

如何理解.NET4并行編程中Task的取消

如何理解.NET 4并行編程中Task的取消,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

成都創(chuàng)新互聯(lián)公司從2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目網(wǎng)站制作、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元內(nèi)丘做網(wǎng)站,已為上家服務(wù),為內(nèi)丘各地企業(yè)和個人服務(wù),聯(lián)系電話:18982081108

因為Task是.NET 4并行編程最為核心的一個類,也我們在是在并行編程常常打交道的類,所以,對Task對全面的了解很有必要。

小編主要講述如何取消一個task。

在TPL中一個標準化的操作就是”取消Task”。之所以說它是個標準化的操作,其實是把這個操作和之前傳統(tǒng)的多線程編程進行比較而言的。

在之前的多線程編程中,我們一般是自己寫一些代碼來取消線程的運行。但是在.NET 4的TPL中就內(nèi)置了取消的方法,可能我們覺得TPL沒有必要內(nèi)置這些代碼,因為太簡單了。但是這個內(nèi)置的方法不僅僅只是取消了運行的Task,而且還減小了在取消運行的Task時可能產(chǎn)生的一些風險,我們后續(xù)文章會詳細講述。

創(chuàng)建一個取消的Task一般要進行下面一些步驟:

a.創(chuàng)建System.Threading.CancellationTokenSource的一個實例:

// create the cancellation token source  ancellationTokenSource tokenSource = new CancellationTokenSource();

b.通過CancellationTokenSource.Token屬性獲得一個System.Threading.CancellationToken:

CancellationToken token = tokenSource.Token;

c.創(chuàng)建一個新的Task或者Task<T>,并且在構(gòu)造函數(shù)傳入Action或者Action<object>的委托作為***個參數(shù),傳入CancellationToken作為第二個參數(shù):

Task task = new Task(new Action(printMessage), token);

d.調(diào)用Task的Start()方法。

上面的步驟和我們之前介紹的創(chuàng)建一個Task的代碼幾乎一樣,只是在構(gòu)造函數(shù)中多傳入了一個參數(shù)。

如果想要取消一個Task的運行,只要調(diào)用CancellationToken實例的Cancel()方法就可以了。

有點要特別注意的,當我們調(diào)用了Cancel()方法之后,.NET Framework不會強制性的去關(guān)閉運行的Task。

我們自己必須去檢測之前在創(chuàng)建Task時候傳入的那個CancellationToken。

我們在創(chuàng)建Task是傳入CancellationToken到構(gòu)造函數(shù),其實這個CancellationToken就是.NET Framework用來避免我們再次運行已經(jīng)被取消的Task,可以說就是一個標志位。

首先,進入***個議題:

1.通過輪詢的方式檢測Task是否被取消

在很多Task內(nèi)部都包含了循環(huán),用來處理數(shù)據(jù)。我們可以在循環(huán)中通過CancellationToken的IsCancellationRequest屬性來檢測task是否被取消了。如果這個屬性為true,那么我們就得跳出循環(huán),并且釋放task所占用的資源(如數(shù)據(jù)庫資源,文件資源等).

我們也可以在task運行體中拋出System.Threading.OperationCanceledException來取消運行的task。

代碼如下:

代碼

while (true)  {      if (token.IsCancellationRequested)      {            // tidy up and release resources             throw new OperationCanceledException(token);      }       else      {          // do a unit of work         }   }

如果我們沒有任何的資源要釋放,那么只要簡單的調(diào)用CancellationToken.ThrowIfCancellationRequested()方法,這個方法會檢查是否要取消task,并且拋出異常。代碼如下:

while (true)          token.ThrowIfCancellationRequested();          // do a unit of work  }

下面就給出有一個完整的例子:創(chuàng)建一個可以取消的task,并且通過輪詢不斷的檢查是否要取消task

代碼如下:

代碼       

static void Main(string[] args)          {              // create the cancellation token source              CancellationTokenSource tokenSource = new CancellationTokenSource();               // create the cancellation token              CancellationToken token = tokenSource.Token;              // create the task               Task task = new Task(() =>              {                  for (int i = 0; i < int.MaxValue; i++)                  {                      if (token.IsCancellationRequested)                      {                          Console.WriteLine("Task cancel detected");                          throw new OperationCanceledException(token);                      }                      else                     {                          Console.WriteLine("Int value {0}", i);                      }                  }              }, token);               // wait for input before we start the task              Console.WriteLine("Press enter to start task");              Console.WriteLine("Press enter again to cancel task");              Console.ReadLine();               // start the task              task.Start();               // read a line from the console.              Console.ReadLine();               // cancel the task              Console.WriteLine("Cancelling task");              tokenSource.Cancel();               // wait for input before exiting              Console.WriteLine("Main method complete. Press enter to finish.");              Console.ReadLine();          }

2.       用委托delegate來檢測Task是否被取消

我們可以在注冊一個委托到CancellationToken中,這個委托的方法在CancellationToken.Cancel()調(diào)用之前被調(diào)用。

我們可以用這個委托中的方法來作為一個檢測task是否被取消的另外一個可選的方法,因為這個方法是在Cancel()方法被調(diào)用之前就調(diào)用的,所以這個委托中的方法可以檢測task是否被cancel了,也就是說,只要這個委托的方法被調(diào)用,那么就說這個CancellationToken.Cancel()方法被調(diào)用了,而且在這個委托的方法中我們可以做很多的事情,如通知用戶取消操作發(fā)生了。

下面的代碼給出了一個例子。

代碼       

static void Main(string[] args)          {              // create the cancellation token source              CancellationTokenSource tokenSource = new CancellationTokenSource();               // create the cancellation token              CancellationToken token = tokenSource.Token;               // create the task              Task task = new Task(() =>              {                  for (int i = 0; i < int.MaxValue; i++)                  {                      if (token.IsCancellationRequested)                      {                          Console.WriteLine("Task cancel detected");                          throw new OperationCanceledException(token);                      }                      else                     {                          Console.WriteLine("Int value {0}", i);                      }                  }              }, token);               // register a cancellation delegate              token.Register(() =>              {                  Console.WriteLine(">>>>>> Delegate Invoked\n");              });               // wait for input before we start the task              Console.WriteLine("Press enter to start task");              Console.WriteLine("Press enter again to cancel task");              Console.ReadLine();               // start the task              task.Start();              // read a line from the console.              Console.ReadLine();               // cancel the task              Console.WriteLine("Cancelling task");              tokenSource.Cancel();               // wait for input before exiting              Console.WriteLine("Main method complete. Press enter to finish.");              Console.ReadLine();          }

3.       用Wait Handle還檢測Task是否被取消

第三種方法檢測task是否被cancel就是調(diào)用CancellationToken.WaitHandle屬性。對于這個屬性的詳細使用,在后續(xù)的文章中會深入的講述,在這里主要知道一點就行了:CancellationToken的WaitOne()方法會阻止task的運行,只有CancellationToken的cancel()方法被調(diào)用后,這種阻止才會釋放。

在下面的例子中,創(chuàng)建了兩個task,其中task2調(diào)用了WaitOne()方法,所以task2一直不會運行,除非調(diào)用了CancellationToken的Cancel()方法,所以WaitOne()方法也算是檢測task是否被cancel的一種方法了。

代碼       

static void Main(string[] args)         {              // create the cancellation token source             CancellationTokenSource tokenSource = new CancellationTokenSource();              // create the cancellation token             CancellationToken token = tokenSource.Token;              // create the task             Task task1 = new Task(() =>             {                 for (int i = 0; i < int.MaxValue; i++)                 {                     if (token.IsCancellationRequested)                     {                         Console.WriteLine("Task cancel detected");                         throw new OperationCanceledException(token);                     }                     else                    {                         Console.WriteLine("Int value {0}", i);                     }                 }             }, token);              // create a second task that will use the wait handle             Task task2 = new Task(() =>             {                 // wait on the handle                 token.WaitHandle.WaitOne();                 // write out a message                 Console.WriteLine(">>>>> Wait handle released");             });              // wait for input before we start the task             Console.WriteLine("Press enter to start task");             Console.WriteLine("Press enter again to cancel task");             Console.ReadLine();             // start the tasks             task1.Start();             task2.Start();              // read a line from the console.             Console.ReadLine();              // cancel the task             Console.WriteLine("Cancelling task");             tokenSource.Cancel();              // wait for input before exiting             Console.WriteLine("Main method complete. Press enter to finish.");             Console.ReadLine();         }

4.      取消多個Task

我們可以使用一個CancellationToken來創(chuàng)建多個不同的Tasks,當這個CancellationToken的Cancel()方法調(diào)用的時候,使用了這個token的多個task都會被取消。

代碼       

static void Main(string[] args)          {              // create the cancellation token source              CancellationTokenSource tokenSource = new CancellationTokenSource();               // create the cancellation token              CancellationToken token = tokenSource.Token;               // create the tasks              Task task1 = new Task(() =>              {                  for (int i = 0; i < int.MaxValue; i++)                  {                      token.ThrowIfCancellationRequested();                      Console.WriteLine("Task 1 - Int value {0}", i);                  }              }, token);               Task task2 = new Task(() =>              {                  for (int i = 0; i < int.MaxValue; i++)                  {                      token.ThrowIfCancellationRequested();                      Console.WriteLine("Task 2 - Int value {0}", i);                  }              }, token);              // wait for input before we start the tasks              Console.WriteLine("Press enter to start tasks");              Console.WriteLine("Press enter again to cancel tasks");              Console.ReadLine();               // start the tasks              task1.Start();              task2.Start();               // read a line from the console.              Console.ReadLine();               // cancel the task              Console.WriteLine("Cancelling tasks");              tokenSource.Cancel();              // wait for input before exiting              Console.WriteLine("Main method complete. Press enter to finish.");              Console.ReadLine();          }

5. 創(chuàng)建組合的取消Task的Token

我們可以用CancellationTokenSource.CreateLinkedTokenSource()方法來創(chuàng)建一個組合的token,這個組合的token有很多的CancellationToken組成。主要組合token中的任意一個token調(diào)用了Cancel()方法,那么使用這個組合token的所有task就會被取消。代碼如下:

代碼       

static void Main(string[] args)         {             // create the cancellation token sources             CancellationTokenSource tokenSource1 = new CancellationTokenSource();             CancellationTokenSource tokenSource2 = new CancellationTokenSource();             CancellationTokenSource tokenSource3 = new CancellationTokenSource();              // create a composite token source using multiple tokens             CancellationTokenSource compositeSource =                  CancellationTokenSource.CreateLinkedTokenSource(             tokenSource1.Token, tokenSource2.Token, tokenSource3.Token);              // create a cancellable task using the composite token             Task task = new Task(() =>             {                 // wait until the token has been cancelled                 compositeSource.Token.WaitHandle.WaitOne();                 // throw a cancellation exception                 throw new OperationCanceledException(compositeSource.Token);             }, compositeSource.Token);              // start the task             task.Start();              // cancel one of the original tokens             tokenSource2.Cancel();              // wait for input before exiting             Console.WriteLine("Main method complete. Press enter to finish.");             Console.ReadLine();         }

6.      判斷一個Task是否已經(jīng)被取消了

可以使用Task的IsCancelled屬性來判斷task是否被取消了。代碼如下:

代碼       

static void Main(string[] args)         {             // create the cancellation token source             CancellationTokenSource tokenSource1 = new CancellationTokenSource();              // create the cancellation token             CancellationToken token1 = tokenSource1.Token;              // create the first task, which we will let run fully             Task task1 = new Task(() =>             {                 for (int i = 0; i < 10; i++)                 {                     token1.ThrowIfCancellationRequested();                     Console.WriteLine("Task 1 - Int value {0}", i);                 }             }, token1);              // create the second cancellation token source             CancellationTokenSource tokenSource2 = new CancellationTokenSource();              // create the cancellation token             CancellationToken token2 = tokenSource2.Token;              // create the second task, which we will cancel             Task task2 = new Task(() =>             {                 for (int i = 0; i < int.MaxValue; i++)                 {                     token2.ThrowIfCancellationRequested();                     Console.WriteLine("Task 2 - Int value {0}", i);                 }             }, token2);              // start all of the tasks             task1.Start();             task2.Start();              // cancel the second token source             tokenSource2.Cancel();             // write out the cancellation detail of each task             Console.WriteLine("Task 1 cancelled? {0}", task1.IsCanceled);             Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled);             // wait for input before exiting             Console.WriteLine("Main method complete. Press enter to finish.");             Console.ReadLine();         }

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。

分享文章:如何理解.NET4并行編程中Task的取消
分享路徑:http://jinyejixie.com/article24/gpijje.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計、軟件開發(fā)、定制網(wǎng)站App開發(fā)、網(wǎng)站設(shè)計公司網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)
城口县| 黄浦区| 哈巴河县| 信阳市| 和龙市| 九台市| 岢岚县| 观塘区| 凤冈县| 兴国县| 海安县| 叶城县| 盐津县| 长丰县| 嘉黎县| 固镇县| 吉木乃县| 陆良县| 婺源县| 洱源县| 宜城市| 浑源县| 曲靖市| 乌兰浩特市| 娱乐| 大足县| 河间市| 当涂县| 高青县| 寿宁县| 长海县| 如皋市| 淅川县| 南陵县| 富锦市| 新巴尔虎左旗| 永平县| 麻栗坡县| 东方市| 界首市| 余庆县|