در این مقاله قصد داریم یاد بگیریم که چگونه Long Running Task را با استفاده از روش Cancellationtokensource در .NET 4.0 لغو یا قطع کنیم.
بنابراین، وظیفه اینجاست: برنامه وب من با برقراری تماس API سرویس وب، درخواست POST را ارسال می کند و داده ها را از طریق یک کتابخانه شخص ثالث دریافت می کند. به عنوان مثال، در نظر بگیرید، برنامه قرار است جزئیات مربوط به دانشآموزان را از طریق API ارسال کند و زمانی که دادههای POST با موفقیت دریافت شد و در سمت دیگری ذخیره شد، پاسخ را دریافت خواهد کرد. در نظر بگیرید که برنامه قرار است 5000 بیت داده را از طریق API ارسال کند. بنابراین، با استفاده از هر حلقه با فراخوانی API شخص ثالث، میتوانیم 5000 داده را پست کنیم.
اتمام این کار خیلی طول می کشد. تا زمانی که این کار انجام نشود، برنامه اجازه نمی دهد تا عملیات دیگر انجام شود زیرا کار در رشته اصلی در حال اجرا است. برای ایجاد امکان، به "TASK" منتقل می شویم تا این کار را در یک موضوع جداگانه اجرا کنیم تا برنامه بتواند عملیات دیگری را انجام دهد. برای درک این موضوع به کد زیر نگاهی بیندازید.
- Var task=Task.Factory.StartNew(()=> CallWebServiceandGetResponceData());
این کد وظیفه ای را ایجاد می کند که در تابع CallWebServiceandGetResponceData برای ارسال درخواست و دریافت داده های پاسخ، سرویس وب API را فراخوانی می کند. بنابراین با این کار اپلیکیشن این عملیات وظیفه را در یک رشته مجزا اجازه می دهد و می توانیم عملیات دیگری را در نخ اصلی انجام دهیم که تاثیری در عملیات وظیفه نخواهد داشت. همه چیز خوب پیش می رود.
اگر از .NET 4.5 Framework استفاده می کنید، می توانید از Async استفاده کنید و منتظر کلمات کلیدی برای انجام این کار باشید. اما در .NET 4.0 نمیتوانیم از کلمات کلیدی async استفاده کنیم و منتظر بمانیم، بنابراین میخواهم از "TASK" برای رسیدن به این عملیات استفاده کنم.
بنابراین، اکنون باید هر زمان که لازم باشد، کار را لغو یا متوقف کنم. برای مثال، دادههای 2673 در حال حاضر در تابع CallWebServiceandGetResponceData در حال اجرا هستند، وقتی دکمه توقف را فشار میدهم باید تماس API شخص ثالث را لغو یا متوقف کنم و از حلقه خارج شوم. برای این کار از CancellationToken استفاده می کنم.
.NET 4.0 ساختاری سبک به نام cancellationToken را معرفی می کند که مکانیزمی برای لغو عملیات همزمان و ناهمزمان ارائه می دهد. CancellationToken شامل یک روش CancellationRequested است، این یک ویژگی بولی است که می توان آن را با کد نظرسنجی کرد تا متوجه شد آیا لغو شده است یا درخواست لغو شده است.
با استفاده از نمونه ای از کلاس CancellationTokenSource برای دریافت نشانه لغو، در مدل لغو، نشانه لغو می تواند آزادانه به شنوندگان منتقل شود، به طوری که نشانه لغو به طور کامل از توانایی مصرف درخواست لغو جدا می شود. این کد نمونه برای لغو یک کار است،
- CancellationTokenSource mCancellationTokenSource = new CancellationTokenSource();
- CancellationToken token = mCancellationTokenSource.Token;
- Task < string > ObjTask = Task.Factory.StartNew(() => {
- while (!token.IsCancellationRequested) {
- try {
- For(i = 0; i < totalrecordscount; i++) {
- If(i == 2341) {
- Token.Cancecl();
- }
- // Sending data to other end by api call
- }
- } catch () {
- return;
- }
- }
- return;
- }, token);
کد بالا به طور مداوم در حلقه while اجرا می شود تا زمانی که درخواست لغو را دریافت کند. هنگامی که توکن درخواست لغو دریافت کرد، کنترل کل Task را خاتمه می دهد و کنترل به موضوع اصلی باز می گردد. در اینجا، درخواست لغو در داخل وظیفه بر اساس شرایط انجام می شود.
در عوض، ما همچنین میتوانیم هر زمان که بخواهیم، کار را متوقف کنیم، مانند پس از شروع اجرای کار، وقتی دکمه توقف را از جلویی فشار میدهم، درخواست لغو توکن را دریافت کرده و اجرا را خاتمه میدهم. در اینجا، کد نمونه برای لغو یک کار با کلیک کردن روی دکمه توقف است:
- Bool istasktostop = false; // declare one global bool variable
- CancellationTokenSource mCancellationTokenSource = new CancellationTokenSource();
- CancellationToken token = mCancellationTokenSource.Token;
- Task < string > ObjTask = Task.Factory.StartNew(() => {
- while (!token.IsCancellationRequested) {
- try {
- For(i = 0; i < totalrecordscount; i++) {
- //for each loop its checking weather “istasktostop” is
- If(istasktostop) {
- Token.Cancecl();
- }
- // Sending data to other end by api call
- }
- } catch () {
- return;
- }
- }
- return;
- }, token);
- protected void Stop_Sending_Click(object sender, ImageClickEventArgs e) {
- istasktostop = true;
- }
به طور معمول، اگر همان عملیات را بدون کار و نشانه لغو انجام دادیم، نمیتوانیم درخواست توقف را زمانی که فرآیند در حالت در حال اجرا است ارسال کنیم، زیرا فرآیند فعلی رشته اصلی را اشغال میکند و نمیتوانیم رشته اصلی را در حین اجرای آن قطع کنیم. وقتی همان فرآیند را در داخل وظیفه انجام دادیم، آن را جدا کرده و در یک رشته جداگانه اجرا می کنیم، بنابراین می توانیم پردازش های دیگر را در موضوع اصلی انجام دهیم.
امیدوارم این مقاله مفید باشد. با تشکر.