3 Stimmen

Unbehandelte Ausnahmen vom verwalteten C#-Benutzersteuerelement, das im MFC-Dialog verwendet wird

Unsere Kernanwendung ist in MFC C++ erstellt, aber wir versuchen, neuen Code in .NET zu schreiben, und haben ein Benutzersteuerelement in .NET erstellt, das auf einem vorhandenen MFC-Dialog verwendet wird.

Wenn jedoch eine unerwartete/unbehandelte Ausnahme von der Benutzersteuerung ausgelöst wird, führt dies zum Absturz der MFC-Anwendung (illegaler Op-Stil), ohne dass eine Wiederherstellung möglich ist.

Ich habe hinzugefügt

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

an den Konstruktor des .NET-Benutzersteuerelements, aber es scheint nichts zu fangen.

Gibt es eine Möglichkeit, ein Ereignis in MFC hinzufügen, um diese zu behandeln?

Ein schnelles Googeln hat nichts Brauchbares ergeben.

Danke.


Edit: Ich habe es immer noch nicht geschafft, das Problem so zu lösen, wie ich es gerne hätte. am besten Weg, um es zu tun, ist versuchen und fangen um alle .NET-Code, so dass keine Ausnahmen Blase auf.

3voto

Aidan Ryan Punkte 11109

Ich habe diese Frage schon vor einiger Zeit gestellt: Endgültiger Managed Exception Handler in einer gemischten nativen/managed ausführbaren Datei?

Was ich gefunden habe, ist, dass die verwalteten unbehandelten Ausnahmeereignisse NUR ausgelöst werden, wenn in einem verwalteten Thread ausgeführt. Die verwaltete WndProc ist, wo die Magie passiert.

Sie haben mehrere Möglichkeiten: Sie könnten einen Low-Level-Override in CWinApp platzieren und Exception^ abfangen. Dies könnte unbeabsichtigte Nebeneffekte haben. Oder Sie könnten mit Structured Exception Handling (SEH) gehen, die Ihnen einen Hack auf / alle/ unbehandelten Ausnahmen geben wird. Dies ist kein einfacher Weg.

0voto

Ich denke, Sie wollen die unbehandelte Ausnahme-Handler in der MFC-Seite der Dinge haben:

AppDomain::CurrentDomain->UnhandledException += gcnew UnhandledExceptionEventHandler(&CurrentDomain_UnhandledException);

[auch für Application.ThreadException]

Werfen Sie einen Blick auf diese ähnliche Frage in den MSDN-Foren: Unbehandelte Ausnahme in einer Mixed-Mode-Anwendung

0voto

John Saunders Punkte 159011

Natürlich wäre es besser, die Ausnahme im C#-Code zu behandeln oder herauszufinden, was sie verursacht, und sie so zu beheben, dass die Ausnahme nie ausgelöst wird. Was verhindert das?

Setzen Sie in jeden Event-Handler der Benutzersteuerung einen try/catch-Block:

private void btnOk_Click(object sender, EventArgs e) {
    try {
        // real code here
    }
    catch (Exception ex) {
        LogException(ex);
        // do whatever you must in order to shut down the control, maybe just
    }
}

Ich verwende Folgendes:

public static class UI
{
    public static void PerformUIAction(Control form, Action action)
    {
        PerformUIAction(form, action, (string) null);
    }

    public static void PerformUIAction(
        Control form, Action action, string message)
    {
        PerformUIAction(form, action, () => message);
    }

    public static void PerformUIAction(
        Control form, Action action, Func<string> messageHandler)
    {
        var saveCursor = form.Cursor;
        form.Cursor = Cursors.WaitCursor;
        try
        {
            action();
        }
        catch (Exception ex)
        {
            MessageBox.Show(
                messageHandler() ?? ex.Message, "Exception!",
                MessageBoxButtons.OK, MessageBoxIcon.Error,
                MessageBoxDefaultButton.Button1,
                MessageBoxOptions.DefaultDesktopOnly);
            Debug.WriteLine(ex.ToString(), "Exception");
            throw;
        }
        finally
        {
            form.Cursor = saveCursor;
        }
    }
}

Ich nenne es so:

private void _copyButton_Click(object sender, EventArgs e)
{
    UI.PerformUIAction(
        this, () =>
                  {
                  // Your code here
                  });
}

0voto

Ich habe den Handler für unbehandelte Ausnahmen in den Konstruktor des .NET-Benutzersteuerelements eingefügt

Ich glaube nicht, dass das funktioniert; ich glaube, der Exception-Handler muss vor einem Aufruf von Application.Run eingerichtet werden. Haben Sie irgendwelche Application.Run-Aufrufe in Ihrer Anwendung?

Wie wäre es mit etwas wie dies auf der MFC-Seite der Dinge, bevor Sie alle .NET-Steuerelemente initialisieren:

Application.SetUnhandledExceptionMode(System.Windows.Forms.UnhandledExceptionMode.CatchException);
Application.ThreadException += ...;

Überprüfen Sie, ob der ThreadException-Handler aufgerufen wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X