سؤال

تأكيد System.Threading.Tasks.Task البنائين يأخذون أ CancellationToken كمعلمة:

CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);

ما يحيرني حول هذا هو أنه لا توجد طريقة من داخل تم تمرير طريقة الحصول على الجسم فعليًا في الرمز المميز (على سبيل المثال ، لا شيء مثل Task.CurrentTask.CancellationToken). يجب توفير الرمز المميز من خلال بعض الآليات الأخرى ، مثل كائن الحالة أو التقاطها في لامدا.

إذن ما الغرض الذي يخدم الرمز المميز للإلغاء في المنشئ؟

هل كانت مفيدة؟

المحلول

إن تمرير هذا الرمز المميز إلى مُنشئ المهمة يربطه بهذه المهمة.

اقتباس إجابة ستيفن توب من MSDN:

هذا له فوائد أساسية:

  1. إذا كان الرمز المميز قد تم الإلغاء قبل بدء المهمة ، فلن يتم تنفيذ المهمة. بدلا من الانتقال إلى Running, ، سوف ينتقل على الفور إلى Canceled. هذا يتجنب تكاليف تشغيل المهمة إذا تم إلغاؤها فقط أثناء التشغيل على أي حال.
  2. إذا كان جسم المهمة يراقب أيضًا رمز الإلغاء ويرمي OperationCanceledException تحتوي على هذا الرمز المميز (وهو ما ThrowIfCancellationRequested يفعل) ، ثم عندما ترى المهمة ذلك OperationCanceledException, ، يتحقق ما إذا كان OperationCanceledExceptionالرمز المميز يطابق رمز المهمة. إذا كان الأمر كذلك ، يُنظر إلى هذا الاستثناء على أنه إقرار بإلغاء التعاون والتحولات المهمة إلى الحالة الملغاة (بدلاً من الحالة المعطلة).

نصائح أخرى

يستخدم المنشئ الرمز المميز للتعامل مع الإلغاء داخليًا. إذا كان الرمز الخاص بك يرغب في الوصول إلى الرمز المميز ، فأنت مسؤول عن نقله إلى نفسك. أوصي بشدة بقراءة ملف برمجة متوازية مع Microsoft .NET Book في CodePlex.

مثال استخدام CTS من الكتاب:

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

Task myTask = Task.Factory.StartNew(() =>
{
    for (...)
    {
        token.ThrowIfCancellationRequested();

        // Body of for loop.
    }
}, token);

// ... elsewhere ...
cts.Cancel();

الإلغاء ليس حالة بسيطة كما يعتقد الكثيرون. تم شرح بعض التفاصيل الدقيقة في منشور المدونة هذا على MSDN:

فمثلا:

في بعض المواقف في امتدادات متوازية وفي أنظمة أخرى ، من الضروري إيقاظ طريقة محظورة لأسباب لا ترجع إلى الإلغاء الصريح من قبل المستخدم. على سبيل المثال ، إذا تم حظر مؤشر ترابط واحد على blockingcollection.take () نظرًا لأن المجموعة فارغة وتراجع مؤشر ترابط آخر فيما بعد blockingcollection.CompleTeadding () ، فيجب أن تستيقظ المكالمة الأولى وتلقي على سبيل المثال لتمثيل استخدام غير صحيح.

http://blogs.msdn.com/b/pfxteam/archive/2009/06/22/9791840.aspx

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top