معالج الاستثناء المُدار النهائي في ملف قابل للتنفيذ مختلط أصلي/مُدار؟

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

سؤال

لدي تطبيق MFC تم تجميعه باستخدام /clr وأحاول تنفيذ معالج نهائي للاستثناءات المُدارة التي لم يتم اكتشافها.بالنسبة للاستثناءات الأصلية، تجاوز CWinApp::ProcessWndProcException يعمل.

الحدثان المقترحان في جيف مقالة مشروع الكود,Application.ThreadException و AppDomain.CurrentDomain.UnhandledException, ، لا يتم رفعها.

هل يمكن لأي شخص أن يقترح طريقة لتوفير معالج الاستثناء المُدار النهائي للملف القابل للتنفيذ المختلط؟


تحديث:

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

في سؤال منتدى MSDN حول هذا الموضوع، تم اقتراح تجاوز نقطة ذات مستوى منخفض بدرجة كافية لسلسلة رسائل MFC الرئيسية في ملف try ... catch (Exception^).على سبيل المثال، CWinApp::Run.قد يكون هذا حلاً جيدًا لكنني لم ألقي نظرة على أي آثار تتعلق بالأداء أو الاستقرار.ستتاح لك فرصة تسجيل الدخول باستخدام مكدس الاستدعاءات قبل الكفالة ويمكنك تجنب سلوك الاستثناء غير المعالج للنوافذ الافتراضي.

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

المحلول

من خلال إلقاء نظرة على شبكات الإنترنت، ستجد أنك بحاجة إلى تثبيت عامل تصفية للحصول على الاستثناءات غير المُدارة التي تمرر المرشحات في طريقها إلى AppDomain الخاص بك.من CLR ومرشحات الاستثناءات غير المعالجة:

يعتمد CLR على آلية تصفية الاستثناءات غير المعالجة SEH لالتقاط الاستثناءات غير المعالجة.

نصائح أخرى

يجب أن يعمل استخدام هذين المعالجين الاستثناءين.

لماذا يجب؟"

لا يتم رفع الأحداث باستخدام ما يلي:

extern "C" void wWinMainCRTStartup();

// managed entry point
[System::STAThread]
int managedEntry( void )
{
    FinalExceptionHandler^ handler = gcnew FinalExceptionHandler();

    Application::ThreadException += gcnew System::Threading::ThreadExceptionEventHandler(
                                        handler,
                                        &FinalExceptionHandler::OnThreadException);

    AppDomain::CurrentDomain->UnhandledException += gcnew UnhandledExceptionEventHandler(
                                                        handler,
                                                        &FinalExceptionHandler::OnAppDomainException);

    wWinMainCRTStartup();

    return 0;
}

// final thread exception handler implementation
void FinalExceptionHandler::OnThreadException( Object^ /* sender */, System::Threading::ThreadExceptionEventArgs^ t )
{
    LogWrapper::log->Error( "Unhandled managed thread exception.", t->Exception );
}

// final appdomain exception handler implementation
void FinalExceptionHandler::OnAppDomainException(System::Object ^, UnhandledExceptionEventArgs ^args)
{
    LogWrapper::log->Error( "Unhandled managed appdomain exception.", (Exception^)(args->ExceptionObject) );
}

BOOL CMyApp::InitInstance()
{
    throw gcnew Exception("test unhandled");
    return TRUE;
}

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

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