| 

.NET C# Java Javascript Exception

2
Hallo,

vielleicht gibt es ja eine viel einfachere Lösung zu meinem Problem. Zur Erläuterung, wie das Topic entsteht: ich habe ein Formular mit einem Panel. Das Panel wird zur Laufzeit mit Formularen gefüllt (da sind ein paar Textboxen, Labels und Buttons drin), in etwa so (dt ist eine gefüllte DataTable, die Quelle für die Forulare):

Dim loc As UInteger = 0
panel1.Controls.Clear()
For Each dr as DataRow In dt.Rows
Dim tmpfrm As New unterform
tmpfrm.TopLevel = False
tmpfrm.Visible = True'<- hier crashet es
'weitere Eigenschaften schreiben
tmpfrm.Location = New Point(0, loc)
loc = loc + tmpfrm.Height
Panel1.Controls.Add(tmpfrm)
Next

Durch einen Klick auf einen Reload-Button wird das Panel neu befüllt. Allerdings crashet es bei genau 912 Formularen. Also habe ich panel1.Controls.Clear ersetzt durch

For Each cntl As unterform In Panel1.Controls
cntl.Close()
cntl.Dispose()
Next

Nach dem ersten Befüllen (500 Formulare) zeigt der Taskmanager ca. 90 MB Speicherverbrauch an. Nach dem Klick auf den Reload-Button sinkt das kurzzeitig auf ca. 70 MB, steigt dann auf knapp 120 MB an, bevor ich die Exception bekomme.

Googeln hat mir auch keine Lösung gebracht. Close() und Dispose() scheint nicht ganz zu machen, was ich mir vorstelle. Wie schmeiße ich die Dinger jetzt richtig(er) raus?

Vielen Dank!

Edit: Ich benutze WinForms.
28.01.2013
muffi 1,4k 1 9
muffi 1,4k 1 9
3 Antworten
1
Für den Fall, dass irgendwann mal jemand dieses Problem bekommt: nach dem Trial-and-Error-Prinzip habe ich der Klasse eine sub dazugefügt, das scheint zumindest zu funktionieren. Und im Taskmanager kann man damit auch feststellen, dass der Speicher jetzt auch komplett wieder freigegeben wird.

Public Sub selbstzerstoerung()
Me.DestroyHandle()
Me.Dispose(False)
End Sub
29.01.2013
muffi 1,4k 1 9
0
Es gibt ein Limit von 10.000 Window-Handles pro Prozess. Wobei nicht nur die Formulare zählen, sondern auch die Controls darauf - da braucht auch jedes ein Handle. Vermutlich stößt Du mit Deinen 912 Formularen an diese Grenze.

Disposen von nicht mehr benötigten Controls ist im Prinzip schon der richtige Weg. Aber Du darfst eben auch nicht zu viele erzeugen.
28.01.2013
Matthias Hlawatsch 13,2k 4 9
Wie gesagt, beim Start werden (im Moment) 500 Elemente erzeugt. Erst, wenn ich das Panel neu schreiben lasse, knallt es praktisch bei 412 (dann sind die 912 erreicht). Die Schleife mit dem Disposen der unterforms scheint also nicht richtig zu funzen. Wenn ich die Forms auf 100 limitiere, muss ich halt 9x auf Reload klicken, damit es knallt (damit ich nicht so oft klicken muss, ist es auf 500 gestellt ;-) ).
muffi 28.01.2013
OK, das hatte ich aus Deiner Frage nicht so klar herauslesen können. Auf den ersten Blick scheint mir der gepostete Code ok zu sein. Aber wie ist denn die Klasse unterform aufgebaut? Verhindert dort vielleicht irgendwas das ordnungsgemäße Disposen des Forms und all seiner Kinder?
Matthias Hlawatsch 28.01.2013
Oh, ich hatte gar keine Mail bekommen, dass ein neuer Kommentar da ist. Aber nein: ich bin mir keiner Schuld bewusst, die das Disposen verhindert. Ob meine Lösung mit der Selbstzerstörung nun die Allerbeste ist, weiß ich nicht, aber scheint zu funzen.
muffi 29.01.2013
0
Ein Fall für GC.Collect() ?
Deine Situation scheint mir ein Fall zu sein, bei dem ein gezielter Aufruf des GarbageCollectors helfen könnte. Einen Versuch ist es wert - und sei es nur deshalb, um herauszufinden, ob es in Deinem Fall funktionieren würde. Mich würde es auf alle Fälle interessieren, da ich sehr selten darüber nachdenke, den GC explizit anzuschubsen. Würde mich freuen, wenn Du es testet und mir/uns mitteilst, ob es hilft. Danke.
29.01.2013
ffordermaier 8,4k 3 9
Ich habe es sogar mit GC.WaitForPendingFinalizers():GC.Collect() versucht - hatte keine Auswirkung. Es hat immer genau an der gleichen Stelle geknallt.
muffi 29.01.2013
Ok, danke für die Info.
ffordermaier 29.01.2013

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH