مشاركة عبر


المهام التابعة و مهام متداخلة

مهمة متداخلة هو فقط على Taskالمثيل هو تاريخ الإنشاء بتفويض مستخدم لمهمة أخرى. على المهام التابعة هو المتداخلة المهام هو تم إنشاؤه مع AttachedToParentخيار. مهمة قد إنشاء أي عدد من الطفل و/او مهام متداخلة، محدودا فقط بموارد النظام. يظهر المثال التالي مهمة أصل الذي يقوم بإنشاء واحد مهمة بسيطة المتداخلة.

Shared Sub SimpleNestedTask()
    Dim parent = Task.Factory.StartNew(Sub()
                                           Console.WriteLine("Outer task executing.")
                                           Dim child = Task.Factory.StartNew(Sub()
                                                                                 Console.WriteLine("Nested task starting.")
                                                                                 Thread.SpinWait(500000)
                                                                                 Console.WriteLine("Nested task completing.")
                                                                             End Sub)
                                       End Sub)
    parent.Wait()
    Console.WriteLine("Outer task has completed.")


End Sub

' Sample output:
'   Outer task executing.
'   Nested task starting.
'   Outer task has completed.
'   Nested task completing.
static void SimpleNestedTask()
{
    var parent = Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Outer task executing.");

        var child = Task.Factory.StartNew(() =>
        {
            Console.WriteLine("Nested task starting.");
            Thread.SpinWait(500000);
            Console.WriteLine("Nested task completing.");
        });
    });

    parent.Wait();
    Console.WriteLine("Outer has completed.");
}

/* Sample output:
        Outer task executing.
        Nested task starting.
        Outer has completed.
        Nested task completing.
 */

المرفق فرع مهام مقابل مفصول مهام متداخلة

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

Dim child = Task.Factory.StartNew(Sub()
                                      Console.WriteLine("Attached child starting.")
                                      Thread.SpinWait(5000000)
                                      Console.WriteLine("Attached child completing.")
                                  End Sub, TaskCreationOptions.AttachedToParent)
var child = Task.Factory.StartNew((t) =>
{

    Console.WriteLine("Attached child starting.");
    Thread.SpinWait(5000000);
    Console.WriteLine("Attached child completing.");
},                TaskContinuationOptions.AttachedToParent);

سوف يتم إنتاج الإخراج التالي.

' Parent task executing.
' Attached child starting.
' Attached child completing.
' Parent has completed.
Parent task executing.
Attached child starting.
Attached child completing.
Parent has completed.

يمكنك استخدام المهام التابعة المتصلة إلى إنشاء رسومات متزامنة بشكل كبير من العمليات غير المتزامنة. ومع ذلك، في معظم الحالات، فإننا نوصي باستخدام مهام متداخلة لأن العلاقات مع غير ذلك المهام أقل تعقيداً. هو سبب متداخلة المهام التي تم إنشاؤها داخل المهام الأخرى بشكل افتراضي، ويجب تحديد بشكل واضح AttachedToParentخيار إلى إنشاء مهمة التابعة.

يسرد الجدول التالي الاختلافات أساسى بين نوعين من فرع المهام.

Category

مهام متداخلة

المرفق فرع المهام

مهمة الخارجية (الأصل) ينتظر المهام الداخلية إلى كاملة.

لا

نعم

نشر الأصل استثناءات طرح بواسطة الأطفال (مهام الداخلي).

لا

نعم

حالة الأصل (خارجية مهمة) تعتمد تشغيل حالة التابعة (الداخلي مهمة).

لا

نعم

في وحدات سيناريو فصل الموقع مهمة المتداخلة هو Task<TResult>، لا يزال يمكنك فرض الأصل لانتظار فرع عن طريق الوصول إلى Resultخاصية لمهام متداخلة. Resultحظر خاصية حتى يتم اكتمال مهمة الخاصة بها.

Shared Sub WaitForSimpleNestedTask()
    Dim parent = Task(Of Integer).Factory.StartNew(Function()
                                                       Console.WriteLine("Outer task executing.")
                                                       Dim child = Task(Of Integer).Factory.StartNew(Function()
                                                                                                         Console.WriteLine("Nested task starting.")
                                                                                                         Thread.SpinWait(5000000)
                                                                                                         Console.WriteLine("Nested task completing.")
                                                                                                         Return 42
                                                                                                     End Function)
                                                       Return child.Result


                                                   End Function)
    Console.WriteLine("Outer has returned {0}", parent.Result)
End Sub
'Sample output:
' Outer task executing.
' Nested task starting.
' Detached task completing.
' Outer has returned 42
static void WaitForSimpleNestedTask()
{
    var outer = Task<int>.Factory.StartNew(() =>
    {
        Console.WriteLine("Outer task executing.");

        var nested = Task<int>.Factory.StartNew(() =>
        {
            Console.WriteLine("Nested task starting.");
            Thread.SpinWait(5000000);
            Console.WriteLine("Nested task completing.");
            return 42;
        });

        // Parent will wait for this detached child.
        return nested.Result;
    });

    Console.WriteLine("Outer has returned {0}.", outer.Result);
}

/* Sample output:
    Outer task executing.
    Nested task starting.
    Nested task completing.
    Outer has returned 42.
 */

الاستثناءات في المتداخل ومهام فرع

إذا يطرح tكـk متداخلة استثناء، يجب أن تكون العينتين أو معالجة مباشرة في tكـk الخارجية فقط كـ مع أي tكـk غير متداخلة. إذا كان يطرح تابعة المتصلة استثناء ‏‏ استثناء هو المنشورة بشكل تلقائي إلى المهمة الأصلية والعودة إلى مؤشر ترابط الذي ينتظره أو يحاول الوصول إلى خاصية نتيجة للمهمة. ولذلك، باستخدام المهام التابعة المتصلة، يمكنك معالجة الجميع الاستثناءات عند يؤشر واحدة فقط، واستدعاء namely إلى انتظار في مؤشر ترابط استدعاء. لمزيد من المعلومات، راجع ‏‏ استثناء معالجة (مكتبة متوازى المهام).

مهام فرع والإلغاء

تذكر أن إلغاء المهمة هو التعاونية. ولذلك، إلى أن "cancelable،" يجب مهمة التابعة لمرفق أو فصل كل moniإلىr حالة الإلغاء إلى ken. إذا كنت تريد إلى "إلغاء الأمر الأمر" الأصل وكافة التوابع الخاصة به باستخدام واحد من إلغاء الأمر طلب، ثم المرور نفس إلى ken كوسيطة إلى كافة المهام وتوفير المعلومات المنطقية في كل مهمة إلى الاستجابة إلى الطلب. للمزيد من المعلومات، راجع إلغاء مهمة وكيفية القيام بما يلي: إلغاء الأمر مهمة و الخاص الأطفال.

عند إلغاء الأصل

في حالة إلغاء أصل نفسه قبل تابع هو بدء مهمة التابعة (المتداخلة) obviously إلا ستبدأ. إذا كان أصل يلغي نفسه بعد فرع أو لقد تم مسبقاً بدء مهمة متداخلة، ستعمل مهمة المتداخلة (المستوى الفرع) إلى الإكمال إلا إذا كان يحتوي على منطق الإلغاء الخاص به. لمزيد من المعلومات، راجع إلغاء مهمة.

عند إلغاء مهمة متداخلة

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

عند إلغاء مهمة فرع

عندما مهمة تابعة المتصلة إلغاء نفسه باستخدام نفس الرمز المميز الذي تم تمريره إلى مهمة، TaskCanceledExceptionهو نشرها لمؤشر الترابط ضم داخل AggregateException. من المهم جداً للانتظار تشغيل مهمة الأصلية بحيث يمكنك معالجة الجميع الاستثناءات benign بالإضافة إلى الجميع الاستثناءات faulting التي تم نشرها حتى من خلال رسم بياني للمهام التابعة المتصلة.

لمزيد من المعلومات، راجع ‏‏ استثناء معالجة (مكتبة متوازى المهام).

راجع أيضًا:

المبادئ

البرمجة المتوازية في .NET Framework

بيانات متوازى ism (مكتبة متوازى المهام)