سؤال

لذلك، أعلم أن المحاولة/الالتقاط تضيف بعض النفقات العامة وبالتالي فهي ليست طريقة جيدة للتحكم في تدفق العملية، ولكن من أين تأتي هذه النفقات العامة وما هو تأثيرها الفعلي؟

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

المحلول

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

لا أعتقد أن هذه مشكلة طالما أنك تستخدم استثناءات للسلوك الاستثنائي (وبالتالي ليس المسار النموذجي المتوقع عبر البرنامج).

نصائح أخرى

ثلاث نقاط يجب توضيحها هنا:

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

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

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

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

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

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

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

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

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

bool HasRight(string rightName, DomainObject obj) {
  try {
    CheckRight(rightName, obj);
    return true;
  }
  catch (Exception ex) {
    return false;
  }
}

void CheckRight(string rightName, DomainObject obj) {
  if (!_user.Rights.Contains(rightName))
    throw new Exception();
}

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

لذلك قمت بإعادة هيكلتها إلى ما يلي، والذي - وفقًا للقياسات السريعة والقذرة اللاحقة - أسرع بحوالي أمرين من حيث الحجم:

bool HasRight(string rightName, DomainObject obj) {
  return _user.Rights.Contains(rightName);
}

void CheckRight(string rightName, DomainObject obj) {
  if (!HasRight(rightName, obj))
    throw new Exception();
}

باختصار، فإن استخدام الاستثناءات في تدفق العملية العادي يكون أبطأ بمقدار أمرين تقريبًا من استخدام تدفق عملية مماثل بدون استثناءات.

ناهيك عن أنه إذا كان داخل طريقة يتم الاتصال بها بشكل متكرر، فقد يؤثر ذلك على السلوك العام للتطبيق.
على سبيل المثال، أعتبر استخدام Int32.Parse ممارسة سيئة في معظم الحالات لأنه يطرح استثناءات لشيء يمكن اكتشافه بسهولة بخلاف ذلك.

لذا ختاما لكل ما كتب هنا:
1) استخدم كتل المحاولة..التقاط الأخطاء غير المتوقعة - لا يوجد أي عقوبة على الأداء تقريبًا.
2) لا تستخدم استثناءات للأخطاء المستثناة إذا كان بإمكانك تجنبها.

لقد كتبت مقالا عن هذا منذ فترة لأنه كان هناك الكثير من الناس يسألون عن هذا في ذلك الوقت.يمكنك العثور عليه ورمز الاختبار على http://www.blackwasp.co.uk/SpeedTestTryCatch.aspx.

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

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

انا صنعت دخول بلوق حول هذا الموضوع العام الماضي.تحقق من ذلك.خلاصة القول هي أنه لا توجد أي تكلفة تقريبًا لمجموعة المحاولة في حالة عدم حدوث أي استثناء - وعلى الكمبيوتر المحمول الخاص بي، كان الاستثناء حوالي 36 ميكرو ثانية.قد يكون هذا أقل مما كنت تتوقعه، ولكن ضع في اعتبارك أن تلك النتائج تكون على كومة ضحلة.كما أن الاستثناءات الأولى بطيئة جدًا.

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

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

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

وخلافا للنظريات المقبولة عموما، try/catch يمكن أن يكون لها آثار كبيرة على الأداء، وذلك سواء تم طرح الاستثناء أم لا!

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

تمت تغطية الأول في بضع منشورات مدونة بواسطة Microsoft MVPs على مر السنين، وأنا على ثقة من أنه يمكنك العثور عليها بسهولة ولكن StackOverflow يهتم بكثير عن محتوى لذلك سأقدم روابط لبعض منهم كما حشو شهادة:

هناك ايضا هذه الإجابة مما يوضح الفرق بين الكود المفكك مع وبدون استخدام try/catch.

يبدو من الواضح أن هناك يكون وهو عبء يمكن ملاحظته بشكل صارخ في إنشاء التعليمات البرمجية، ويبدو أن هذا الحمل يتم الاعتراف به من قبل الأشخاص الذين يقدرون Microsoft!ومع ذلك فأنا، تكرار الانترنت...

نعم، هناك العشرات من تعليمات MSIL الإضافية لسطر واحد بسيط من التعليمات البرمجية، وهذا لا يغطي حتى التحسينات المعطلة، لذا فهو من الناحية الفنية تحسين دقيق.


لقد نشرت إجابة منذ سنوات وتم حذفها لأنها ركزت على إنتاجية المبرمجين (التحسين الكلي).

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

من الواضح أننا يجب أن نكون كذلك تحسين أولوياتنا, ، وليس فقط الكود الخاص بنا!في إجابتي الأخيرة، استندت إلى الاختلافات بين مقتطفين من التعليمات البرمجية.

استخدام try/catch:

int x;
try {
    x = int.Parse("1234");
}
catch {
    return;
}
// some more code here...

عدم استخدام try/catch:

int x;
if (int.TryParse("1234", out x) == false) {
    return;
}
// some more code here

ضع في اعتبارك من وجهة نظر مطور الصيانة، الأمر الذي من المرجح أن يضيع وقتك، إن لم يكن في التوصيف/التحسين (المذكور أعلاه) والذي من المحتمل أنه لن يكون ضروريًا لولا try/catch مشكلة، ثم في التمرير خلال التعليمات البرمجية المصدر...واحد من هؤلاء لديه أربعة أسطر إضافية من القمامة المعيارية!

ومع إدخال المزيد والمزيد من الحقول في الفصل الدراسي، تتراكم كل هذه البيانات غير الرسمية (سواء في التعليمات البرمجية المصدر أو المفككة) بشكل يتجاوز المستويات المعقولة.أربعة أسطر إضافية لكل حقل، وهي دائمًا نفس الأسطر...ألم نتعلم تجنب تكرار أنفسنا؟أعتقد أنه يمكننا إخفاء try/catch وراء بعض التجريدات المخمرة في المنزل، ولكن...عندها يمكننا أيضًا تجنب الاستثناءات (أييستخدم Int.TryParse).

هذا ليس حتى مثالا معقدا.لقد رأيت محاولات لإنشاء فئات جديدة في try/catch.ضع في اعتبارك أن كل التعليمات البرمجية الموجودة داخل المُنشئ قد يتم استبعادها بعد ذلك من بعض التحسينات التي قد يتم تطبيقها تلقائيًا بواسطة المترجم.ما هي أفضل طريقة لإثارة النظرية القائلة بأن المترجم بطيء, ، في مقابل يقوم المترجم بالضبط بما يُطلب منه القيام به?

بافتراض أن المُنشئ المذكور قد طرح استثناءً، وتم تشغيل بعض الأخطاء نتيجة لذلك، يتعين على مطور الصيانة الضعيف تعقبه.قد لا تكون هذه مهمة سهلة، على عكس كود السباغيتي الخاص بـ اذهب إلى كابوس، try/catch يمكن أن يسبب فوضى في ثلاثة أبعاد, ، لأنه يمكن أن ينتقل إلى أعلى المكدس ليس فقط إلى أجزاء أخرى من نفس الطريقة، ولكن أيضًا إلى فئات وأساليب أخرى، والتي سيتم ملاحظتها جميعًا بواسطة مطور الصيانة، الطريق الصعب!ومع ذلك قيل لنا أن "goto أمر خطير"، هه!

وفي النهاية أذكر، try/catch له فائدته وهي إنه مصمم لتعطيل التحسينات!إنها، إذا صح التعبير، أ مساعدات التصحيح!هذا ما صممت من أجله وهذا ما يجب أن تستخدمه...

أعتقد أن هذه نقطة إيجابية أيضًا.يمكن استخدامه لتعطيل التحسينات التي قد تؤدي إلى تعطيل خوارزميات تمرير الرسائل الآمنة والعقلانية للتطبيقات متعددة الخيوط، وللتعرف على ظروف السباق المحتملة؛) هذا هو السيناريو الوحيد الذي يمكنني التفكير فيه لاستخدام المحاولة/الالتقاط.وحتى هذا لديه بدائل.


ما تفعله التحسينات try, catch و finally إبطال؟

الملقب ب

كيف try, catch و finally مفيدة كمساعدات التصحيح؟

إنها حواجز الكتابة.ويأتي هذا من المعيار:

12.3.3.13 بيانات محاولة الالتقاط

للحصول على بيان com.stmt النموذج:

try try-block
catch ( ... ) catch-block-1
... 
catch ( ... ) catch-block-n
  • حالة التعيين المحددة لـ الخامس في بداية محاولة كتلة هو نفس حالة التعيين المحددة لـ الخامس في بداية com.stmt.
  • حالة التعيين المحددة لـ الخامس في بداية قبض على كتلة ط (لأي أنا) هي نفس حالة التعيين المحددة لـ الخامس في بداية com.stmt.
  • حالة التعيين المحددة لـ الخامس عند نقطة نهاية com.stmt يتم تعيينه بالتأكيد إذا (وفقط إذا) الخامس تم تعيينه بالتأكيد عند نقطة نهاية محاولة كتلة وكل قبض على كتلة ط (لكل أنا من 1 إلى ن).

وبعبارة أخرى، في بداية كل منها try إفادة:

  • جميع المهام التي تم إجراؤها على الأشياء المرئية قبل الدخول try يجب أن يكون البيان كاملاً، الأمر الذي يتطلب قفل مؤشر ترابط للبدء، مما يجعله مفيدًا لتصحيح أخطاء ظروف السباق!
  • لا يُسمح للمترجم بما يلي:
    • قم بإزالة تعيينات المتغير غير المستخدمة والتي تم تعيينها بالتأكيد قبل try إفادة
    • إعادة تنظيم أو دمج أي منها المهام الداخلية (أي.راجع الرابط الأول الخاص بي، إذا لم تكن قد قمت بذلك بالفعل).
    • رفع المهام فوق هذا الحاجز، لتأخير التعيين إلى متغير يعرف أنه لن يتم استخدامه حتى وقت لاحق (إذا تم استخدامه على الإطلاق) أو لتحريك المهام اللاحقة بشكل استباقي للأمام لإجراء تحسينات أخرى ممكنة...

قصة مماثلة تحمل لكل منهما catch إفادة؛لنفترض داخل الخاص بك try العبارة (أو المُنشئ أو الوظيفة التي تستدعيها، وما إلى ذلك) التي تقوم بتعيينها لهذا المتغير الذي لا معنى له (على سبيل المثال، garbage=42;)، لا يستطيع المترجم حذف هذه العبارة، بغض النظر عن مدى عدم ارتباطها بالسلوك الملحوظ للبرنامج.المهمة يجب أن يكون مكتمل قبل catch تم إدخال الكتلة.

لما يستحق، finally يحكي بالمثل تدهور قصة:

12.3.3.14 عبارات المحاولة الأخيرة

ل يحاول إفادة com.stmt النموذج:

try try-block
finally finally-block

• حالة التعيين المحددة الخامس في بداية محاولة كتلة هو نفس حالة التعيين المحددة لـ الخامس في بداية com.stmt.
• حالة التعيين المحددة الخامس في بداية أخيرا كتلة هو نفس حالة التعيين المحددة لـ الخامس في بداية com.stmt.
• حالة التعيين المحددة الخامس عند نقطة نهاية com.stmt يتم تعيينه بالتأكيد إذا (وفقط إذا) إما:س الخامس تم تعيينه بالتأكيد عند نقطة نهاية محاولة كتلةس الخامس تم تعيينه بالتأكيد عند نقطة نهاية أخيرا كتلةإذا كان نقل تدفق التحكم (مثل اذهب إلى بيان) الذي يبدأ في الداخل محاولة كتلة, ، وينتهي خارج محاولة كتلة, ، ثم الخامس يعتبر أيضًا معينًا بالتأكيد على نقل تدفق التحكم إذا الخامس تم تعيينه بالتأكيد عند نقطة نهاية أخيرا كتلة.(هذه ليست مجرد إذا — إذا الخامس تم تعيينه بالتأكيد لسبب آخر في نقل تدفق التحكم هذا، فإنه لا يزال يعتبر معينًا بالتأكيد.)

12.3.3.15 عبارات محاولة الالتقاط أخيرًا

تحليل مهمة محددة ل يحاول-يمسك-أخيراً بيان النموذج:

try try-block
catch ( ... ) catch-block-1
... 
catch ( ... ) catch-block-n
finally finally-block

يتم كما لو كان البيان أ يحاول-أخيراً البيان المرفق أ يحاول-يمسك إفادة:

try { 
    try   
    try-block
    catch ( ... ) catch-block-1
    ...   
    catch ( ... ) catch-block-n
} 
finally finally-block

أنا حقا أحب Hafthor مشاركة مدونة, ولإضافة سنتي إلى هذه المناقشة، أود أن أقول إنه كان من السهل دائمًا بالنسبة لي أن أجعل DATA LAYER يلقي نوعًا واحدًا فقط من الاستثناءات (DataAccessException).بهذه الطريقة، تعرف طبقة الأعمال الخاصة بي الاستثناء المتوقع وتدركه.ثم اعتمادًا على قواعد العمل الإضافية (أيإذا كان كائن العمل الخاص بي يشارك في سير العمل وما إلى ذلك)، فقد أقوم بطرح استثناء جديد (BusinessObjectException) أو المتابعة دون إعادة/رمي.

أود أن أقول لا تتردد في استخدام حاول..التقط كلما كان ذلك ضروريًا واستخدمه بحكمة!

على سبيل المثال، تشارك هذه الطريقة في سير العمل...

تعليقات؟

public bool DeleteGallery(int id)
{
    try
    {
        using (var transaction = new DbTransactionManager())
        {
            try
            {
                transaction.BeginTransaction();

                _galleryRepository.DeleteGallery(id, transaction);
                _galleryRepository.DeletePictures(id, transaction);

                FileManager.DeleteAll(id);

                transaction.Commit();
            }
            catch (DataAccessException ex)
            {
                Logger.Log(ex);
                transaction.Rollback();                        
                throw new BusinessObjectException("Cannot delete gallery. Ensure business rules and try again.", ex);
            }
        }
    }
    catch (DbTransactionException ex)
    {
        Logger.Log(ex);
        throw new BusinessObjectException("Cannot delete gallery.", ex);
    }
    return true;
}

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

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

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

دعونا نحلل إحدى أكبر التكاليف المحتملة لحظر المحاولة/الالتقاط عند استخدامها حيث لا يلزم استخدامها:

int x;
try {
    x = int.Parse("1234");
}
catch {
    return;
}
// some more code here...

وإليك ما هو بدون المحاولة/الالتقاط:

int x;
if (int.TryParse("1234", out x) == false) {
    return;
}
// some more code here

بغض النظر عن المسافة البيضاء غير المهمة، قد يلاحظ المرء أن هاتين القطعتين المتساويتين من التعليمات البرمجية لهما نفس الطول تقريبًا بالبايت.يحتوي الأخير على مسافة بادئة أقل بمقدار 4 بايت.هل هذا شيء سيء؟

ولزيادة الطين بلة، يقرر الطالب إجراء حلقة بينما يمكن تحليل الإدخال باعتباره int.قد يكون الحل بدون المحاولة/الالتقاط شيئًا مثل:

while (int.TryParse(...))
{
    ...
}

ولكن كيف يبدو هذا عند استخدام المحاولة/الالتقاط؟

try {
    for (;;)
    {
        x = int.Parse(...);
        ...
    }
}
catch
{
    ...
}

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

إحدى التكاليف الأقل هي أن كتل المحاولة/الالتقاط تؤدي بالفعل إلى تعطيل بعض التحسينات: http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implications-of-try-catch-finally.aspx.أعتقد أن هذه نقطة إيجابية أيضًا.يمكن استخدامه لتعطيل التحسينات التي قد تؤدي إلى تعطيل خوارزميات تمرير الرسائل الآمنة والعقلانية للتطبيقات متعددة الخيوط، وللتعرف على ظروف السباق المحتملة؛) هذا هو السيناريو الوحيد الذي يمكنني التفكير فيه لاستخدام المحاولة/الالتقاط.وحتى هذا لديه بدائل.

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