کنسل کردن Taskها
کی از مباحث جدید در Task Programming Library بحث کنسل کردن Task ها می باشد. البته با روشهای معمول برنامه نویسی ترید ها نیز میتوان امر را محقق نمود اما خب در دات نت 4 برای کاهش ریسک خطاهای نا خواسته تدابیر بخصوصی اندیشیده شده است. در ادامه خواهید دید چگونه میتوان یک Task را کنسل کرد یا حتی آن را بخواب برد.
ایجاد یک Task که آن را بتوان براحتی کنسل کرد دارای چهار مرحله است :
مرحله اول - یک نمونه از کلاس System.Threading.CancellationTokenSource را ایجاد کنید:
CancellationTokenSource tokenSource = new CancellationTokenSource;
مرحله دوم - یک نمونه از کلاس CancellationToken را ایجاد کرده و آن را با استفاده از خصوصیت Token نمونه کلاسی که در مرحله قبلی ایجاد کردیم مقدار دهی می کنیم:
CancellationToken token = tokenSource.Token;
مرحله سوم – یک نمونه از Task را که دارای نوع خروجی باشد را ایجاد میکنیم این Task باید از متغیر token که در مرحله قبلی ایجاد کردیم و یک delegate Action بعنوان بدنه استفاده کند:
Task task1 = new Task(new Action(myMethod), token);
خب الان چطور این Task را کنسل کنیم؟
براحتی میتوان متد Cancel از شی tokenSource را صدا کرد و Task را کنسل نمود.
دات نت یک Task را مجبور به کنسل شدن نمیکند . خود برنامه باید CancellationTokenSource را زیر نظر بگیرد و زمانی که درخواست کنسل شدن Task رسیدبا کمک آن Task را کنسل کند. به این پروسه اصطلاحاًیک فرایند Cooperative گویند.
پس برای کنسل کردن مونیتور کردن یک Task بسیار مهم است. در ادامه به انواع روشهای مونیتور کردن Task ها می پردازیم.
مونیتور کردن فرایند کنسل شدن بروش نظر سنجی یا Polling
در بدنه بعضی از Taskها حلقه هایی برای پردازش اطلاعات وجود دارد . در این حلقه ها میتوان با بررسی مقدار true خصوصیت IsCancellationRequested که در کلاس CancellationToken وجود دارد از حلقه خارج شد و منابع 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 } }
اگر هیچ منبعی در Task مورداستفاده قرار نگرفته است براحتی میتوانید با استفاده از متد ThrowIfCancellationRequested کد بالا را ساده نمود:
while (true) { token.ThrowIfCancellationRequested(); // do a unit of work } }
اکنون به یک مثال کاملتر میپردازیم :
using System; using System.Threading; using System.Threading.Tasks; namespace Listing_07 { class Listing_07 { 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(); } } }
0 نظرات:
ارسال یک نظر