كيفية التقاط جميع الاستثناءات/الأعطال في تطبيق .NET [نسخة مكررة]

StackOverflow https://stackoverflow.com/questions/82483

  •  01-07-2019
  •  | 
  •  

سؤال

التكرار المحتمل:
.NET - ما هي أفضل طريقة لتنفيذ "معالج التقاط كافة الاستثناءات"

لدي تطبيق تطبيق .NET console الذي يتعطل ويعرض رسالة للمستخدم.كل الكود الخاص بي موجود في ملف try{<code>} catch(Exception e){<stuff>} كتلة، ولكن لا تزال تظهر الأخطاء في بعض الأحيان.

في تطبيق Win32، يمكنك التقاط جميع الاستثناءات/الأعطال المحتملة عن طريق تثبيت معالجات الاستثناءات المختلفة:

/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler

ما هو المعادل في عالم .NET حتى أتمكن من التعامل مع/تسجيل/تهدئة جميع حالات الخطأ المحتملة؟

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

المحلول

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

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

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

نصائح أخرى

يمكنك إضافة معالج حدث إلى حدث AppDomain.UnhandledException، وسيتم استدعاؤه عند طرح استثناء وعدم اكتشافه.

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

ال Global.asax الطبقة هي خط الدفاع الأخير الخاص بك.ينظر الى:

protected void Application_Error(Object sender, EventArgs e)

طريقة

انتبه إلى أن بعض الاستثناءات قد يكون من الخطورة اكتشافها - أو لا يمكن اكتشافها في الغالب،

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

يمكنك استخدام AppDomain.CurrentDomain.UnhandledException للحصول على حدث.

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

على أية حال، عادةً ما أستخدم:

AppDomain.CurrentDomain.UnhandledException

يمكنك أيضًا الانتقال إلى حدث Application.ThreadException.

ذات مرة كنت أقوم بتطوير تطبيق .NET يعمل داخل تطبيق يستند إلى COM؛كان هذا الحدث مفيدًا للغاية، حيث لم يعمل AppDomain.CurrentDomain.UnhandledException في هذه الحالة.

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

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

لا يؤلمني استخدام كل من AppDomain.currentDomain.UnhandledException Application.ThreadException

لكن ضع في اعتبارك أن الاستثناءات في سلاسل العمليات الثانوية لا يتم اكتشافها بواسطة هذه المعالجات؛يستخدم موضوع آمن للخيوط الثانوية إذا لزم الأمر

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