۱۳۸۹/۱۰/۲۰

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

مونیتور کردن فرایند کنسل شدن با کمک Delegate

براحتی می‌توانید یک Delegate را با یک CancellationToken ثبت کنید و در هنگامی که متد Cancel صدا زده می‌شود از آن استفاده نمود .این روش در برنامه‌هایی که دارای رابط کاربری هستند مثل برنامه‌های WinForm یاWPF مفید است . اگردر Task مورد نظر پروسه غیر همزمان دیگری مثل خواندن و نوشتن روی دیسک انجام می‌شود این روش بسیار مفید است و Delegate ترید اصلی برنامه را براحتی از دریافت درخواست کنسل شدن Task آگاه می کند. مثال :
using System.Threading;

using System.Threading.Tasks;

namespace Listing_08 {

class Listing_08 {

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

}

}

}

تنها تفاوت دو مثال قبلی دراستفاده از متد Register از کلاس CancellationToken می باشد. متد Register یک نمونه از کلاس Action را دریافت کرده و در هنگام کنسل کردن Task نمونه کلاس Action را اجرا می کند.

مونیتور کردن فرایند کنسل شدن با استفاده از هندل انتظار یا Wait Handle


در این روش از متد WaitOne ازخصوصیت WaitHandle کلاس CancellationToken استفاده می‌شود . در مثال زیر دو Task وجود دارد Task دوم متد WaitOne را از token که در Task اول استفاده می‌شود را صدا می‌زند این امر موجب بلاک شدن ترید تا زمان مشخص شدن تکلیف کنسل شدن Task اول می‌شود :

using System;

using System.Threading;

using System.Threading.Tasks;

namespace Listing_09 {

class Listing_09 {

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

}

}

کنسل کردن چندین Task بطور همزمان
با تعریف یک نمونه از کلاس CancellationToken و استفاده از آن در هنگام ایجاد چند Task براحتی می‌توانید با یک بار صدا کردن متد Cancel تمام Task ها را با هم کنسل نمود . مثال :
using System;

using System.Threading;

using System.Threading.Tasks;

namespace Listing_10 {

class Listing_10 {

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

}

}

}
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google
  • Furl
  • Reddit
  • StumbleUpon
  • Donbaleh
  • Technorati
  • Balatarin
  • twitthis

0 نظرات:

ارسال یک نظر