محتويات الدورة

C# / المتوسط: التركيب والعمل غير المتزامن / الدرس 10

الإلغاء وأعمار العمليات

مرر الإلغاء التعاوني وميز طلب التوقف من ملاحظة انتهاء كل عملية مملوكة.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • تعيين ملكية مصدر الإلغاء.
  • تمرير الرموز إلى العمليات الحاجبة الفعلية.
  • تصنيف الإلغاء دون إخفاء فشل آخر.

الإلغاء طلب لا إنهاء قسري

يملك CancellationTokenSource الإشارة وتتيح نسخ الرمز ملاحظتها. يطلب Cancel التعاون وقد ينفذ استدعاءات مسجلة، لكنه لا يقتل الخيوط ولا ينتظر كل مهمة. على المالك انتظار العمل قبل تحرير ما قد يستخدمه. يبقى على المالك معرفة متى انتهت كل مهمة قبل إنهاء اعتمادها، حتى لو عرف الرمز أن الإلغاء مطلوب.

مرر الرمز صراحة عبر الطبقات المناسبة. قبول رمز دون تمريره أوفحصه لا يمنح إلغاء فعليا. تفحص حلقات المعالج دوريا بحد مناسب، ويستخدم الإدخال واجهات واعية أوآلية مقصودة أخرى. إذا لم تدعم عملية قديمة الإلغاء فلا تجعل قبول الرمز في غلافها وعدا زائفا؛ صمم حدها أو وسيلة قطعها صراحة.

ملاحظة عملية ملغاة مضبوطة

يلغي المثال قبل التأخير فتنتهي العملية بالإلغاء دون انتظار ثانية. يتحقق مرشح الالتقاط من الرمز المقصود ويطبع رسالة ثابتة لا نص استثناء محلي أووقت مقاس. ينتهي التأخير المسبق الإلغاء دون سباق يحتاج نوما، فتكون الرسالة المتوقعة نتيجة عقد لا نتيجة قياس.

تمثل OperationCanceledException الفئة العامة وتشتق منها TaskCanceledException. يختلف الإلغاء عن النجاح وفشل الإدخال الآخر. قد يخفي تحويل كل استثناء إلى ملغى عيبا حقيقيا؛ احفظ الفئات الموثقة. يساعد فحص الرمز على عدم نسبة إلغاء عملية أخرى أو فشلها إلى الطلب الحالي بلا دليل.

csharp تأخير واع برمز ملغى مسبقا
using System;
using System.Threading;
using System.Threading.Tasks;

using var source = new CancellationTokenSource();
source.Cancel();
try
{
    await Task.Delay(1000, source.Token);
}
catch (OperationCanceledException exception) when (exception.CancellationToken == source.Token)
{
    Console.WriteLine("cancelled");
}
الناتج المتوقع
cancelled

يلاحظ التأخير الإلغاء فورا ولا يلزم نوم لتوقع الخرج.

جمع إلغاء الأصل والمحلي عمدا

تجمع CreateLinkedTokenSource عمر المستدعي وميزانية محلية. يحرر التخلص التسجيلات ولا يساوي الإلغاء وانتظار العمل. أبق المصدر حيا أثناء الاستخدام المقصود وتخلص بعد ملاحظة الاكتمال. تحرر مصادر الربط تسجيلاتها عند التخلص، وهذه مسؤولية موارد منفصلة عن طلب توقف العمل.

يربط المثال ابنا بالأصل ويلغي الأصل ويفحص الابن دون مهمة خلفية. يضيف timeout مؤقتا ولا يلغي حاجة الملكية. لا تنشئ رمزا منفصلا داخل الطلب فتسقط إلغاء المستدعي سرا. يمنع الربط الصحيح أن تستمر عملية داخلية بعد انتهاء اهتمام المستدعي لمجرد أن لها مؤقتا خاصا.

csharp إشارة إلغاء مترابطة
using System;
using System.Threading;

using var parent = new CancellationTokenSource();
using var child = CancellationTokenSource.CreateLinkedTokenSource(parent.Token);
parent.Cancel();
Console.WriteLine($"parent={parent.IsCancellationRequested} child={child.IsCancellationRequested}");
الناتج المتوقع
parent=True child=True

ينتقل إلغاء الأصل إلى الابن المربوط قبل طبع الحالتين.

تحديد معنى الإلغاء للآثار

قد يتسابق الإلغاء مع النجاح. بعد اعتماد أثر دائم لا يوحي الملغى بأن شيئا لم يحدث. حدد حد الاعتماد والجزئي وكيفية استعادته؛ ليس الرمز مدير معاملات. قد يصل الأثر إلى وجهته ولا تصل استجابته؛ لذلك لا يكفي وصف النتيجة بمهلة كي تصبح الإعادة آمنة.

تحتاج الإعادة بعد مهلة إلى عدم التكرار؛ فقد تضيع الاستجابة بعد النجاح. حد الإعادات بعمر المستدعي ولا تستخدم مصدرا ملغى لعمل آخر. اجعل تنظيف ما بعد الطلب محدود العمر عمدا لا مهمة منفصلة بلا حد. ينبغي أن يميز العقد التنظيف اللازم بعد الإلغاء من عمل جديد انفصل عن الطلب دون مسؤولية اكتمال.

اختبار الإلغاء في كل حجب

اختبر الإلغاء المسبق وأثناء الانتظار والنجاح المتسابق والفشل التابع. استخدم إشارات إكمال لا النوم، واشترط نهاية المهام وحالة المورد لا عودة Cancel فقط. قد يضيف التخلص المبكر من سمافور أودفق أومصدر عيب عمر. تعطي إشارة اكتمال صريحة دليلا على نهاية المستخدم قبل التخلص من مورده، بينما تخمين التأخير لا يفعل.

تجنب callback طويلة حاجبة أوأقفال متعارضة مع الملغي. راجع استثناءاتها وفق الوثائق، وأبلغ الإلغاء عند مالكه حتى لا يسجل الإنهاء العادي كفشل قاتل مرارا. يمكن لاستدعاءات Cancel المسجلة أن تؤثر في خيط الملغي نفسه، لذا راجع طولها وقفلها واستثناءاتها.

الأخطاء الشائعة وإصلاحها

يعود Cancel والعمل يستخدم حالة متخلصا منها.

لماذا يحدث؟
اعتُبر الطلب اكتمالا.
كيف تصلحه؟
انتظر المهام قبل التخلص من اعتمادها.
كيف تتجنب تكراره؟
وثق التوقف والاكتمال منفصلين.

تتجاهل مهلة داخلية إلغاء المستدعي.

لماذا يحدث؟
المصدر المحلي غير مربوط.
كيف تصلحه؟
اربط العمر أومرر الأصل.
كيف تتجنب تكراره؟
اختبر من الخارج.

يصبح كل استثناء نتيجة ملغاة.

لماذا يحدث؟
يخفي الالتقاط العام فشلا آخر.
كيف تصلحه؟
طابق الإلغاء وفق الرمز الموثق.
كيف تتجنب تكراره؟
اختبر فشلا فعليا بجانب الإلغاء.

اختبر فهمك

1. تقبل طريقة رمزا ثم إدخالا طويلا دون رمز. لماذا لا يكفي فحص البداية؟

اعرض الحل المشروح

لا يقطع الإلغاء اللاحق الاستدعاء الجاري. استخدم واجهة واعية أوdeadline أوقطع مورد بعقد أوعملية محدودة. ينقل task مغلف العمل فقط ويبقى انتظار الاكتمال قبل تحرير الاعتمادات لازما.

2. ماذا توثق واجهة لإلغاء بعد اعتماد تحديث وقبل الاستجابة؟

اعرض الحل المشروح

حدد نجاحا معتمدا أوإلغاء بمعرف قابل للاسترداد أوحالة جزئية صريحة ولا تعد بتراجع تلقائي. يحتاج المستدعي سياسة عدم تكرار أواستعلام حالة. اختبر جانبي الاعتماد وافحص الحالة والأثر في تنفيذ اصطناعي.

أهم ما تعلمته

  • الإلغاء تعاوني ولا ينتظر المهام.
  • اربط الأعمار عمدا وتخلص بعد الاستخدام.
  • تبقى حدود الاعتماد والإعادة مسؤولية التطبيق.

المراجع الرسمية