مشاركة عبر


كيفية القيام بما يلي: إيقاف أو تناول وجبة من تكرار حلقي متوازى.For

يوضح المثال التالي كيفية إلى فاصل (أوخروج في Visual أساسى) من Forتكرار حلقي، وأيضا كيفية إلى sإلىp تكرار حلقي. في هذا سياق، تعني "فاصل" إكمال الجميع عمليات تكرار تشغيل الجميع عمليات جزئية التي قبل للتكرار الحالية تشغيل مؤشر ترابط الحالي، ثم قم بإنهاء تكرار حلقي. " توقف"يعني إيقاف الجميع التكرارات كـ قريبا كـ ملائمة.

مثال

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

' How to: Stop or Break from a Parallel.For Loop
Imports System.Collections.Concurrent
Imports System.Threading
Imports System.Threading.Tasks

Module ParallelForStop
    Sub Main()
        StopLoop()
        BreakAtThreshold()

        Console.WriteLine("Press any key to exit.")
        Console.ReadKey()
    End Sub

    Sub StopLoop()
        Console.WriteLine("Stop loop...")
        Dim source As Double() = MakeDemoSource(1000, 1)
        Dim results As New ConcurrentStack(Of Double)()

        ' i is the iteration variable. loopState is a 
        ' compiler-generated ParallelLoopState
        Parallel.For(0, source.Length, Sub(i, loopState)
                                           ' Take the first 100 values that are retrieved
                                           ' from anywhere in the source.
                                           If i < 100 Then
                                               ' Accessing shared object on each iteration
                                               ' is not efficient. See remarks.
                                               Dim d As Double = Compute(source(i))
                                               results.Push(d)
                                           Else
                                               loopState.[Stop]()
                                               Exit Sub

                                           End If
                                           ' Close lambda expression.
                                       End Sub)
        ' Close Parallel.For
        Console.WriteLine("Results contains {0} elements", results.Count())
    End Sub


    Sub BreakAtThreshold()
        Dim source As Double() = MakeDemoSource(10000, 1.0002)
        Dim results As New ConcurrentStack(Of Double)()

        ' Store all values below a specified threshold.
        Parallel.For(0, source.Length, Function(i, loopState)
                                           Dim d As Double = Compute(source(i))
                                           results.Push(d)
                                           If d > 0.2 Then
                                               ' Might be called more than once!
                                               loopState.Break()
                                               Console.WriteLine("Break called at iteration {0}. d = {1} ", i, d)
                                               Thread.Sleep(1000)
                                           End If
                                           Return d
                                       End Function)

        Console.WriteLine("results contains {0} elements", results.Count())
    End Sub

    Function Compute(ByVal d As Double) As Double
        'Make the processor work just a little bit.
        Return Math.Sqrt(d)
    End Function


    ' Create a contrived array of monotonically increasing
    ' values for demonstration purposes. 
    Function MakeDemoSource(ByVal size As Integer, ByVal valToFind As Double) As Double()
        Dim result As Double() = New Double(size - 1) {}
        Dim initialval As Double = 0.01
        For i As Integer = 0 To size - 1
            initialval *= valToFind
            result(i) = initialval
        Next
        Return result
    End Function
End Module
namespace StopOrBreak
{
    using System;
    using System.Collections.Concurrent;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;

    class Test
    {
        static void Main()
        {
            StopLoop();
            BreakAtThreshold();

            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }

        private static void StopLoop()
        {
            Console.WriteLine("Stop loop...");
            double[] source = MakeDemoSource(1000, 1);
            ConcurrentStack<double> results = new ConcurrentStack<double>();

            // i is the iteration variable. loopState is a 
            // compiler-generated ParallelLoopState
            Parallel.For(0, source.Length, (i, loopState) =>
            {
                // Take the first 100 values that are retrieved
                // from anywhere in the source.
                if (i < 100)
                {
                    // Accessing shared object on each iteration
                    // is not efficient. See remarks.
                    double d = Compute(source[i]);
                    results.Push(d);
                }
                else
                {
                    loopState.Stop();
                    return;
                }

            } // Close lambda expression.
            ); // Close Parallel.For

            Console.WriteLine("Results contains {0} elements", results.Count());
        }


        static void BreakAtThreshold()
        {
            double[] source = MakeDemoSource(10000, 1.0002);
            ConcurrentStack<double> results = new ConcurrentStack<double>();

            // Store all values below a specified threshold.
            Parallel.For(0, source.Length, (i, loopState) =>
            {
                double d = Compute(source[i]);
                results.Push(d);
                if (d > .2)
                {
                    // Might be called more than once!
                    loopState.Break();
                    Console.WriteLine("Break called at iteration {0}. d = {1} ", i, d);
                    Thread.Sleep(1000);
                }
            });

            Console.WriteLine("results contains {0} elements", results.Count());
        }

        static double Compute(double d)
        {
            //Make the processor work just a little bit.
            return Math.Sqrt(d);
        }


        // Create a contrived array of monotonically increasing
        // values for demonstration purposes. 
        static double[] MakeDemoSource(int size, double valToFind)
        {
            double[] result = new double[size];
            double initialval = .01;
            for (int i = 0; i < size; i++)
            {
                initialval *= valToFind;
                result[i] = initialval;
            }

            return result;
        }
    }

}

في على ParallelFor()أو [Overload:System.Threading.Tasks.Parallel.Parallel.ForEach`1]تكرار حلقي، لا يمكنك استخدام نفس فاصل أو بيان إنهاء التي هو المستخدمة في تكرار حلقي متسلسلة لأن بنيات بتلك اللغة الصالحة لحلقات متوازية "حلقه" هو أسلوب فعلياً، لا تكرار حلقي. بدلاً من ذلك، استخدم أما في Stopأو Breakالأساليب. بعض التحميلات الزائدة من Parallel.Forيقبل Action<int, ParallelLoopState>(Action(Of Integer, ParallelLoopState)في Visual Bكـic) كـ على معلمة إدخال. ParallelLoopStateالكائن هو تم إنشاؤها في الخلفية بواسطة وقت التشغيل، ويمكنك إعطاء أي اسم ترغب في التعبير لامدا.

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

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

هو يجب فهم التي بعد أما Stopأو Breakهو يسمى، قد يستمر في تكرار حلقي من عمليات جزئية الأخرى ليتم تشغيله لبعض فترة من الوقت، مما هو غير موجودة في عنصر التحكم لمطور تطبيق. يمكنك استخدام ParallelLoopState.IsStoppedالخاصية إلى التحقق ما إذا كان تم الحلقة sإلىpped تشغيل مؤشر ترابط آخر. في المثال التالي، إذا IsStoppedهو true، ثم لا توجد بيانات أخرى هو كتابة إلى مجموعة.

التحويل البرمجي للتعليمات البرمجية

  • نسخة و لصق مثال التعليمة البرمجية في مشروع Visual Basic 2010 Studio.

راجع أيضًا:

المرجع

System.Action<T1, T2>

المبادئ

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

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

لامدا التعبيرات في PLINQ و TPL