۱۳۸۹/۱۰/۲۲

اصول برنامه نویسی موازی درNET. نسخه 4 بخش اول - 6

ایجاد یک کنسل کننده ترکیبی برای چندین Task

می‌توانید با استفاده از چند CancellationToken یک Token ترکیبی ایجاد نمود در این حالت با کنسل شدن هر کدام از Token های زیر مجموعه خود Token اصلی کنسل خواهد شد.این امر با قرار دادن Token ها در متد CreateLinkedTokenSource از کلاس CancellationTokenSource محقق می‌شود مثال :

using System;

using System.Threading;

using System.Threading.Tasks;

namespace Listing_11 {

class Listing_11 {

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();

}

}
}

چگونه می‌توان تعیین کرد یک Task کنسل شده است؟

با استفاده از خصوصیت IsCancelled از کلاس Task می‌توان تعیین نمود که یک Task کنسل شده است یا خیر.

اگر true باشد یعنی فرایند کنسل شدن بدرستی انجام شده است در غیر این صورت Task کنسل نشده است.مثال :

using System;

using System.Threading;

using System.Threading.Tasks;

namespace Listing_12 {

class Listing_12 {

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();

}

}

}
در مثال فوق دو Task ایجاد شده است. هر دو Task از دو CancellationToken مختلف که دو CancellationTokenSource متفاوت دارند استفاده می نمایند. CancellationTokenSource برای Task دوم کنسل می‌شود اما Task اول اجازه دارد که وظیفه‌اش را بطور کامل انجام دهد. خروجی برنامه چنین خواهد بود :
Task 1 cancelled? False Task 2 cancelled? True Task 1 - Int value 0 … Task 1 - Int value 9 Main method complete. Press enter to finish.
انتظار برای گذشت زمان
هنگام کاربا Task ها در برخی از موارد لازم است برای مدت زمانی خاص برنامه درنگ کند.مثلا در هنگام اجرای یک Task لازم است برنامه مقداری را بدست آورد و ادامه برنامه با توجه به مقدار بدست آمده اجرا شود برای این کار لازم است Task برای مدت زمانی خاص صبر کند یا اصطلاحاً بخواب رود.بعد از سپری شدن مدت زمان مورد نظر Task از خواب بیدار شده و کارش را ادامه خواهد داد.در ادامه روشهای خواب کردن Task ها را مورد بررسی قرار خواهیم داد.
استفاده از هندل انتظار Cancellation Token
این روش بهترین راه برای خواب کردن یک Task می باشد.همانطور که قبلاً دیدیم برای اینکه یک Task را کنسل کنیم ابتدا نمونه‌ای از کلاس CancellationTokenSource را تعریف می‌کنیم سپس با کمک خصوصیت Token آن شی CancellationToken را مقدار دهی می‌کنیم در آخر کار با استفاده از متد خصوصیت WaitHandle و متد WaitOne می‌توان Task را کنسل نمود. اما متد WaitOne می‌تواند پارامتری را به عنوان زمان داشته باشد که Task را برای مدت زمانی خاص بر حسب میلی ثانیه قبل از کنسل شدن بخواب ببرد. مثال زیر موضوع را شفاف می‌کند :
using System;

using System.Threading;

using System.Threading.Tasks;

namespace Listing_13 {

class Listing_13 {

static void Main(string[] args) {

// create the cancellation token source

CancellationTokenSource tokenSource = new CancellationTokenSource();

// create the cancellation token

CancellationToken token = tokenSource.Token;

// create the first task, which we will let run fully

Task task1 = new Task(() => {

for (int i = 0; i < Int32.MaxValue; i++) {
// put the task to sleep for 10 seconds

bool cancelled = token.WaitHandle.WaitOne(10000);

// print out a message

Console.WriteLine("Task 1 - Int value {0}. Cancelled? {1}",i, cancelled);

// check to see if we have been cancelled

if (cancelled) {

throw new OperationCanceledException(token);

}

}

}, token);

// start task

task1.Start();

// wait for input before exiting

Console.WriteLine("Press enter to cancel token.");

Console.ReadLine();

// cancel the token

tokenSource.Cancel();

// wait for input before exiting

Console.WriteLine("Main method complete. Press enter to finish.");

Console.ReadLine();

}

}

}
در کد بالا یک Task ایجاد شده که یک پیغام را به خروجی می‌فرستد سپس با استفاده از متد WaitOne به مدت 10 ثانیه بخواب می‌رود .برنامه تا زمان دریافت کلید Enter از کاربر پیغام ها به خروجی می فرستد. و در صورت کنسل شدن Task پایان می‌یابد البته زمانی کنسل شدن صورت می‌گیرد که زمان 10 ثانیه سپری شده باشد.
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google
  • Furl
  • Reddit
  • StumbleUpon
  • Donbaleh
  • Technorati
  • Balatarin
  • twitthis

1 نظرات:

ناشناس گفت...

واقعا ممنون بسيار عالي است

ارسال یک نظر