مشاركة عبر


كيفية القيام بما يلي: استثناءات مؤشر في استعلام PLINQ

يظهر المثال أول في هذا الموضوع كيفية معالجة AggregateExceptionالتي يمكن أن تكون تم طرح من استعلام PLINQ عند تنفيذ. يظهر المثال الثاني كيفية وضع كتل حاول الالتقاط من خلال تفويضات، كـ إغلاق كـ الممكن حيث طرح ‏‏ استثناء. بهذه الطريقة، يمكنك جذب لهم بمجرد أن تحدث كما من الممكن متابعة تنفيذ الاستعلام. عندما مسموح ب‏‏ استثناءات فقاعي للخلف لمؤشر ترابط ضم، ومن ثم هو المحتملة التي قد يستمر استعلام لمعالجة بعض عناصر بعد ‏‏ استثناء هو raهوed.

في بعض الحالات عندما PLINQ يعود إلى تنفيذ متسلسلة، و إستثناء حدوث ‏‏ استثناء قد يمكن نشرة مباشرة، وليس الملتفة في AggregateException. وكذلك ThreadAbortExceptions دوماً نشرها مباشرة.

ملاحظةملاحظة

عند "فقط رمز مجلد" هو ممكناً، إلى قطع Studio Vهوual تشغيل الخط الذي يطرح ‏‏ استثناء و dهوplay رسالة خطأ تقول "لم يتم التعامل معها من قبل المستخدم رمز ‏‏ استثناء." وهذا خطأ هو benign.اضغط على F5 إلى متابعة منه، ومشاهدة سلوك معالجة الاستثناءات التي يتم هو موضح في الأمثلة أدناه.لمنع الانفصال عن الخطأ أول ‏‫Visual Studio، فقط إلغاء تحديد "فقط الخاصة بي تعليمات برمجية" خانة الاختيار تحت أدوات، خيارات، تصحيح، عام.

مثال

يوضح هذا المثال كيفية وضع الكتل حاول الالتقاط حول تعليمات برمجية التي تقوم بتنفيذ الاستعلام لجذب أي AggregateExceptions تم طرح.

' Paste into PLINQDataSample class
Shared Sub PLINQExceptions_1()

    ' Using the raw string array here. See PLINQ Data Sample.
    Dim customers As String() = GetCustomersAsStrings().ToArray()

    ' First, we must simulate some currupt input.
    customers(20) = "###"

    'throws indexoutofrange
    Dim query = From cust In customers.AsParallel() _
        Let fields = cust.Split(","c) _
        Where fields(3).StartsWith("C") _
        Select fields
    Try
        ' We use ForAll although it doesn't really improve performance
        ' since all output is serialized through the Console.
        query.ForAll(Sub(e)
                         Console.WriteLine("City: {0}, Thread:{1}")
                     End Sub)
    Catch e As AggregateException

        ' In this design, we stop query processing when the exception occurs.
        For Each ex In e.InnerExceptions
            Console.WriteLine(ex.Message)
            If TypeOf ex Is IndexOutOfRangeException Then
                Console.WriteLine("The data source is corrupt. Query stopped.")
            End If
        Next
    End Try
End Sub
// Paste into PLINQDataSample class.
static void PLINQExceptions_1()
{
    // Using the raw string array here. See PLINQ Data Sample.
    string[] customers = GetCustomersAsStrings().ToArray();


    // First, we must simulate some currupt input.
    customers[54] = "###";

    var parallelQuery = from cust in customers.AsParallel()
                        let fields = cust.Split(',')
                        where fields[3].StartsWith("C") //throw indexoutofrange
                        select new { city = fields[3], thread = Thread.CurrentThread.ManagedThreadId };
    try
    {
        // We use ForAll although it doesn't really improve performance
        // since all output is serialized through the Console.
        parallelQuery.ForAll(e => Console.WriteLine("City: {0}, Thread:{1}", e.city, e.thread));
    }

    // In this design, we stop query processing when the exception occurs.
    catch (AggregateException e)
    {
        foreach (var ex in e.InnerExceptions)
        {
            Console.WriteLine(ex.Message);
            if (ex is IndexOutOfRangeException)
                Console.WriteLine("The data source is corrupt. Query stopped.");
        }
    }
}

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

يوضح المثال التالي كيفية إلى وضع حظر محاولة catch في تفويض إلى تجعل من الممكن إلى تصفية استثناء ومتابعة تنفيذ الاستعلام.

' Paste into PLINQDataSample class
Shared Sub PLINQExceptions_2()

    Dim customers() = GetCustomersAsStrings().ToArray()
    ' Using the raw string array here.
    ' First, we must simulate some currupt input
    customers(20) = "###"

    ' Create a delegate with a lambda expression.
    ' Assume that in this app, we expect malformed data
    ' occasionally and by design we just report it and continue.
    Dim isTrue As Func(Of String(), String, Boolean) = Function(f, c)

                                                           Try

                                                               Dim s As String = f(3)
                                                               Return s.StartsWith(c)

                                                           Catch e As IndexOutOfRangeException

                                                               Console.WriteLine("Malformed cust: {0}", f)
                                                               Return False
                                                           End Try
                                                       End Function

    ' Using the raw string array here
    Dim query = From cust In customers.AsParallel()
                        Let fields = cust.Split(","c)
                        Where isTrue(fields, "C")
                       Select New With {.City = fields(3)}
    Try
        ' We use ForAll although it doesn't really improve performance
        ' since all output must be serialized through the Console.
        query.ForAll(Sub(e) Console.WriteLine(e.city))


        ' IndexOutOfRangeException will not bubble up      
        ' because we handle it where it is thrown.
    Catch e As AggregateException
        For Each ex In e.InnerExceptions
            Console.WriteLine(ex.Message)
        Next
    End Try
End Sub
// Paste into PLINQDataSample class.
static void PLINQExceptions_2()
{

    var customers = GetCustomersAsStrings().ToArray();
    // Using the raw string array here.
    // First, we must simulate some currupt input
    customers[54] = "###";

    // Create a delegate with a lambda expression.
    // Assume that in this app, we expect malformed data
    // occasionally and by design we just report it and continue.
    Func<string[], string, bool> isTrue = (f, c) =>
    {
        try
        {
            string s = f[3];
            return s.StartsWith(c);
        }
        catch (IndexOutOfRangeException e)
        {
            Console.WriteLine("Malformed cust: {0}", f);
            return false;
        }
    };

    // Using the raw string array here
    var parallelQuery = from cust in customers.AsParallel()
                        let fields = cust.Split(',')
                        where isTrue(fields, "C") //use a named delegate with a try-catch
                        select new { city = fields[3] };
    try
    {
        // We use ForAll although it doesn't really improve performance
        // since all output must be serialized through the Console.
        parallelQuery.ForAll(e => Console.WriteLine(e.city));
    }

    // IndexOutOfRangeException will not bubble up      
    // because we handle it where it is thrown.
    catch (AggregateException e)
    {
        foreach (var ex in e.InnerExceptions)
            Console.WriteLine(ex.Message);
    }
}

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

  • في ترجمة وتشغيل هذه الأمثلة، ونسخها في في مثال لنموذج بيانات PLINQ واستدعاء الأسلوب من الرئيسي.

برمجة نشطة

لا تقوم بتصفية استثناء إلا إذا كنت تعرف كيف إلى معالجة وبالتالي لا يلحق الولاية البرنامج الخاص بك.

راجع أيضًا:

المبادئ

متوازى LINQ (PLINQ)