[VB 2008] Warum dispose aller Fenster bei exit Application.run?

29/07/2010 - 01:44 von Armin Zingler | Report spam
Hi,

ich bin heute auf ein Verhalten gestossen, das ich für nicht so
ganz begrüßenswert halte. Guckst du...:

Public Class Main
Shared Sub Main()

Dim f1, f2, fMain As Form

f1 = New Form With {.Text = "f1"}
f2 = New Form With {.Text = "f2"}

f1.Show()
f2.Show()

fMain = New Form With {.Text = "fMain #1"}
Application.Run(fMain)

End Sub
End Class

Festgestellt habe ich, dass _in_ Application.Run, nachdem fMain geschlossen wurde,
die Dispose-Methode _aller_ geöffneten Fenster aufgerufen wird. Ich finde das nicht
richtig. Deutlich wird das, wenn man nach dem Application.Run diese Zeilen einfügt:

fMain = New Form With {.Text = "fMain #2"}
Application.Run(fMain)

Schließt man nun die erste Instanz von fMain werden f1 und f2 automatisch
geschlossen bevor die zweite Instanz von fMain angezeigt wird. Ja wer
hat das denn erlaubt?? Das soll nicht sein. Oder muss es sein und
warum? Sehe dafür keinen Grund.

Der Callstack in der Dispose-Methode von f1/f2 sieht so aus:

bla.exe!MeineForm.Dispose(Boolean)
System.dll!System.ComponentModel.Component.Dispose()
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadWindows.Dispose()
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows()
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int, int, int)
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int, System.Windows.Forms.ApplicationContext)
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int, System.Windows.Forms.ApplicationContext)
System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
bla.exe!bla.Main.Main()

Es wird offensichtlich ganz radikal 'DisposeThreadWindows' aufgerufen.
Ich bin not amuzed.

Armin
 

Lesen sie die antworten

#1 Thorsten Doerfler
29/07/2010 - 07:46 | Warnen spam
Hallo Armin,
Am 29.07.2010 01:44, schrieb Armin Zingler:

Public Class Main
Shared Sub Main()

Dim f1, f2, fMain As Form

f1 = New Form With {.Text = "f1"}
f2 = New Form With {.Text = "f2"}

f1.Show()
f2.Show()

fMain = New Form With {.Text = "fMain #1"}
Application.Run(fMain)

End Sub
End Class

Festgestellt habe ich, dass _in_ Application.Run, nachdem fMain geschlossen wurde,
die Dispose-Methode _aller_ geöffneten Fenster aufgerufen wird. Ich finde das nicht
richtig.



Ob Du das für richtig hàltst spielt keine Rolle, es ist aber richtig.
Application.Run initiiert die Message Loop Deiner Anwendung. Das
übergebene Form wird zum Hauptformular, an dem sich der Standard
ApplicationContext orientiert, wenn es darum geht die Anwendung zu
beenden. Anwendungsende ist hier dadurch definiert, dass das
Hauptformular geschlossen wird. Ende vom Message Loop bedeutet das Ende
aller Formulare.

Schließt man nun die erste Instanz von fMain werden f1 und f2 automatisch
geschlossen bevor die zweite Instanz von fMain angezeigt wird. Ja wer
hat das denn erlaubt?? Das soll nicht sein.



Wenn das nicht sein soll, verwende Application.Run() ohne Angabe eines
Hauptformulars. Um das Ende der Anwendung bzw. der Message Loop musst Du
Dich dann selber kümmern, denn selbst wenn das letzte Formular
geschlossen wird, làuft Deine Anwendung weiter. Alternative wàre ein
eigener ApplicationContext, der das von Dir gewünschte Verhalten
implementiert und Kontrolle über Deinen Anwendungszustand erlaubt.

Application.Run
http://msdn.microsoft.com/en-us/lib...57900.aspx

ApplicationContext Class
http://msdn.microsoft.com/en-us/lib...ntext.aspx

Btw. das VB Anwendungsframework erlaubt die Wahl, wie das Ende der
Anwendung interpretiert werden soll: Wenn das Haupt-/Startformular
geschlossen wird, oder wenn das letzte Formular geschlossen wird.

Thorsten Dörfler
Microsoft MVP Visual Basic

vb-hellfire visual basic faq | vb-hellfire - einfach anders
http://vb-faq.de/ | http://www.vb-hellfire.de/

Ähnliche fragen