2008-12-23 16 views
5

Ich habe ein untergeordnetes Formular, das eine ApplicationException in den Load-Ereignishandler wirft (absichtlich zu Testzwecken). Das übergeordnete Formular umschließt die ChildForm.Show() - Methode in einem Try ... Catch ex As Exception-Block. Der catch-Block zeigt einfach eine Nachricht an und schließt das untergeordnete Formular. Alles funktioniert wie erwartet, wenn in Visual Studio 2008 (. Net 3.5 SP1) debuggt. Wenn ich es jedoch außerhalb von Visual Studio ausführe, scheint der Catch-Block verpasst zu werden und eine nicht behandelte Ausnahme tritt auf. Irgendeine Idee warum das ist?Catch-Block nicht abfangen

Vielen Dank.

Beispielcode:

Public Class Form1 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Dim f2 As Form2 

     f2 = New Form2 

     Try 
      MessageBox.Show("Opening form 2") 
      f2.ShowDialog() 
     Catch ex As Exception 
      f2.Close() 
      MessageBox.Show("Form 2 closed.") 
     End Try 
    End Sub 

End Class 

Public Class Form2 

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     Throw New ApplicationException("Test Form_Load") 
    End Sub 

    Public Sub New() 

     ' This call is required by the Windows Form Designer. 
     InitializeComponent() 

     ' Add any initialization after the InitializeComponent() call. 
    End Sub 

End Class 

Stack Trace:

 
System.ApplicationException: 
Test Form_Load at WindowsApplication1.Form2.Form2_Load(Object sender, EventArgs e) 
in UnhandledExceptionTest2\WindowsApplication1\Form2.vb 
System.Windows.Forms.Form.OnLoad(EventArgs e) 
System.Windows.Forms.Form.OnCreateControl() 
System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) 
System.Windows.Forms.Control.CreateControl() 
System.Windows.Forms.Control.WmShowWindow(Message& m) at 
System.Windows.Forms.Control.WndProc(Message&> m) at 
System.Windows.Forms.ScrollableControl.WndProc(Message&> m) at 
System.Windows.Forms.ContainerControl.WndProc(Message&> m) at 
System.Windows.Forms.Form.WmShowWindow(Message&> m) at 
System.Windows.Forms.Form.WndProc(Message&> m) at 
System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&> m) at 
System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&> m) at 
System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr 
lparam) 
+0

Können Sie etwas Code posten? –

+0

Ja - es ist vage wie beschrieben ... –

Antwort

11

Das Form.Load-Ereignis verhält sich auf die gleiche Weise wie die meisten anderen Ereignisse in Windows Forms. Es wird von der Nachrichtenschleife ausgelöst, in diesem Fall, wenn Windows die WM_SHOWWINDOW-Nachricht sendet. In der Nachrichtenschleife befindet sich ein Ausnahmebehandler, der verhindert, dass eine nicht abgefangene Ausnahme die Nachrichtenschleife beendet. Dieser Ausnahmehandler löst das Application.ThreadEvent-Ereignis aus. Der Standard-Event-Handler zeigt das nicht behandelte Ausnahmedialogfeld an.

Lange Rede, kurzer Sinn, Sie können eine Ausnahme, die im Load-Ereignis ausgelöst wurde, nicht in Ihrer Click-Handler-Schaltfläche abfangen. Anders als das Abfangen und Behandeln von Ausnahmen im Load-Event-Handler selbst, ist es sehr schwierig, dies richtig zu machen. Ich würde daher empfehlen, dass Sie dem Formular eine öffentliche Methode hinzufügen. Etwas wie Initialisieren(). Verschieben Sie den Code aus Ihrem Load-Ereignis in diese Methode. Rufen Sie Initialize() auf, nachdem Sie die Show() -Methode aufgerufen haben.

+0

+1 Vielen Dank!Schade, es gibt nur einen beschissenen Workaround ... Mehr Code = mehr Bugs ;-) –

+1

All die Jahre, in denen ich 'WinForms' programmiert habe, war das erste Mal, dass ich auf dieses Problem stieß. – AMissico

0

ich für die C# entschuldigen (ich weiß nicht, die Vb-Syntax)

sind Sie so etwas wie dies zu tun:

ChildForm child = new ChildForm(); 
    try { 
     child.Show(); 
    } 
    catch(Exception ex) 
    {.....} 

Wenn s o, ich glaube, das Load-Ereignis würde auf dem New stattfinden, nicht auf der Show(); (Show write fire Activate)

+0

Wenn ich im Debugger durch, tritt das Load-Ereignis auf der Show(). – NYSystemsAnalyst

0

Das neue Fenster hat einen eigenen Thread, der seinen eigenen Ladevorgang ausführt. Um dies zu überprüfen, können Sie versuchen, für einige Sekunden in Form2_Load ein Thread.Sleep vor der Ausnahme zu setzen. Ihr Hauptthreadfenster sollte die Ausführung fortsetzen, bevor Sie die Ausnahme treffen.

+0

Verständlich, kaufen, warum funktioniert der Code in Visual Studio anders als außerhalb von VS? – NYSystemsAnalyst

+0

Hmmm ... Ich habe verpasst, dass es ShowDialog anstelle von Show aufgerufen hat, also sollte es blockieren. Das ist ein wenig verwirrender dann :-( – Yuliy

+0

Wenn ich das Programm außerhalb von VS ausführen, verwenden Sie das Attach to Process ... Tool, und öffnen Sie das Threads and Call Stack-Fenster, beobachten, dass das Form2_Load -Ereignis auf dem Haupt-Thread ausgeführt wird und dass der Aufruf-Stack zeigt Form1_ButtonClick Aufruf Form2_Load. Doch das Verhalten bleibt bestehen. – NYSystemsAnalyst

1

Ich habe das gleiche Problem. Was ich schließlich tat, war, alle Ausnahmen zu fangen. In C#:

Application.ThreadException += new ThreadExceptionEventHandler(MyHandler); 

Und dann das Formular anzeigen.

Ich würde gerne hören, wenn jemand eine bessere Lösung hat.