البرمجة غير المتزامنة قوية، ولكن إدارة المهام وتنظيف الموارد قد يكون معقداً. يشرح هذا المنشور الفرق الجوهري بين 'Cancel()' و 'Dispose()' عند استخدام 'CancellationTokenSource'، مما يساعدك على تجنب الأخطاء الشائعة وكتابة تعليمات برمجية غير متزامنة أنظف وأكثر أماناً.
هل سبق لك أن حاولت إيقاف مهمة تعمل في الخلفية ببرنامجك، فقط لتجد أن الأمور أصبحت فوضوية؟ إذا كنت قد تعمقت في البرمجة غير المتزامنة، خاصة في بيئات مثل Unity، فمن المحتمل أنك واجهت 'CancellationTokenSource'. هذه الأداة المفيدة تساعد في إدارة المهام التي قد تحتاج إلى الإيقاف بلطف، مثل تحميل البيانات أو إدارة استدعاءات الشبكة. ولكن هناك خطأ شائع ينطوي على إجراءين يبدوان متشابهين: 'Cancel()' و 'Dispose()'. دعنا نوضح هذا اللبس. تخيل أنك مدير مكتب مزدحم، وقد أسندت مهمة لموظف. تريد طريقة لإخباره: «مرحباً، أنجز المهمة إذا استطعت». هنا يأتي دور 'CancellationTokenSource'. إنه مثل مساعدك الشخصي لإدارة طلبات «التوقف» هذه. أولاً، لنتحدث عن 'Cancel()'. عندما تستدعي 'cts.Cancel()' (حيث 'cts' هو 'CancellationTokenSource' الخاص بك)، فإنك ترسل أساساً «طلب إلغاء». فكر في الأمر وكأنك ترسل مذكرة لموظفك تقول: «من فضلك توقف عن العمل على هذه المهمة عندما تسنح لك الفرصة». المهم هنا أن هذا مجرد *طلب*. يجب على الموظف (مهمتك الجارية) أن يقرأ هذه المذكرة (يتحقق من 'CancellationToken') ويقرر التوقف. إذا لم يراجعوا المذكرة أبداً، فسيستمرون في العمل! 'Cancel()' لا يوقف المهمة بالقوة؛ بل يشير فقط إلى أنه *يجب* أن تتوقف. الآن، ماذا عن 'Dispose()؟ هذا إجراء مختلف تماماً. عندما تستدعي 'cts.Dispose()'، فأنت لا ترسل طلب إلغاء. بدلاً من ذلك، تقوم بتنظيف كائن 'CancellationTokenSource' نفسه. بالعودة إلى تشبيه المكتب لدينا، 'Dispose()' يشبه تمزيق دفتر المذكرات الخاص بك، ووضع قلمك جانباً، وتنظيف مكتبك لأنك انتهيت من إدارة *أي* طلبات «توقف» محتملة بهذا المساعد المحدد. أنت تحرر الموارد الداخلية التي كان 'CancellationTokenSource' يستخدمها. لماذا هذا التمييز مهم جداً؟ لأن استخدامهما بشكل غير صحيح يمكن أن يؤدي إلى مشاكل. إذا قمت باستدعاء 'Dispose()' ثم حاولت استدعاء 'Cancel()' مرة أخرى على نفس كائن 'CancellationTokenSource'، فكأنك تحاول إرسال مذكرة من دفتر مذكرات قمت بتمزيقه بالفعل – ستحصل على خطأ (يُعرف تقنياً بـ 'ObjectDisposedException')! أيضاً، نسيان استدعاء 'Dispose()' يمكن أن يؤدي إلى احتفاظ برنامجك بموارد غير ضرورية، خاصة عند استخدام ميزات مثل 'CancelAfter()' أو 'CreateLinkedTokenSource()'. ببساطة: استخدم 'Cancel()' عندما تريد أن تتوقف مهمتك الجارية بلطف. استخدم 'Dispose()' عندما تنتهي تماماً من كائن 'CancellationTokenSource' نفسه وتريد تحرير موارده. تأكد دائماً من استدعاء 'Dispose()' لكائنات 'CancellationTokenSource' الخاصة بك *مرة واحدة* عندما تنتهي منها للحفاظ على نظافة التعليمات البرمجية وفعاليتها.