Zum Inhalt springen

C++ PictureBox Dispose


Empfohlene Beiträge

Geschrieben

Hallo,

ich habe folgendes Problem:

Ich habe mir das Spiel Pong als CLR Anwendung programmiert und zeichne dauerhaft in eine PictureBox. Wenn man über einen Menüpunkt den einzelspieler Modus auswählt, wird das Bild aufgebaut, startet aber noch nicht. Wenn ich das Spiel jetzt starte und dann wieder im Menü auf einzelspieler Modus klicke wechselt die horizontale Richtung des Balls, da die PictureBox kurzzeitig eine höhe von 19 pixel hat. Mein Lehrer hat mir jetzt etwas gesagt, dass durch den Menüaufruf eine zu lange lebensdauer der PictureBox entsteht und der Garbage Collector die PictureBox zum Zeichenzeitpunkt schon aus dem Speicher gelöscht wurde.

Er hat kurz etwas angerissen, dass ich mich nach Dispose erkundigen soll, was mich dazu geführt hat, dass ich am Ende der Paint Methode ein e->Dispose(); eingefügt habe. Allerdings muss ich jetzt noch am Anfang dieser Methode eine andere Methode aufrufen, mit der ich der PictureBox angebe, dass sie sich nicht automatisch Disposen soll.

Konnte mir da jemand vll verraten, wie der Befehl dafür lautet?

Ich hoffe es war verständlich, was das Problem ist.

Mfg ShadowmanZ

Geschrieben
Wenn ich das Spiel jetzt starte und dann wieder im Menü auf einzelspieler Modus klicke wechselt die horizontale Richtung des Balls, da die PictureBox kurzzeitig eine höhe von 19 pixel hat.

Das verstehe ich nicht, kannst du das Problem nochmal etwas genauer beschreiben?

Mein Lehrer hat mir jetzt etwas gesagt, dass durch den Menüaufruf eine zu lange lebensdauer der PictureBox entsteht und der Garbage Collector die PictureBox zum Zeichenzeitpunkt schon aus dem Speicher gelöscht wurde.

Das ist Unsinn, es gibt keine zu lange Lebensdauer für ein Control und der Garbage Collector räumt Objecte nur auf wenn diese nicht mehr referenziert werden.

Außerdem solltest du Dispose nicht selber aufrufen sondern dies dem GC überlassen.

Geschrieben
Außerdem solltest du Dispose nicht selber aufrufen sondern dies dem GC überlassen.

Eben nicht! Der GC macht es viel zu früh.

Das verstehe ich nicht, kannst du das Problem nochmal etwas genauer beschreiben?

Ich habe (wie in anderen Programmen: Datei->Speichern) in meinem Programm eine Menüstruktur, die wie folgend aufgebaut ist:

Spiel->Modus->Einzelspieler

Wenn man darauf klickt wird alles initialisiert und gezeichnet.

Sobald man in die PictureBox klickt, fängt alles an sich zu bewegen.

Der Ball wird mit einem Winkel von 30° in die rechte Richtung bewegt. (Rechts oben)

Trifft er an den oberen Rand wechselt der Winkel auf 150°, aber weiterhin rechts. (Rechts unten)

Sobald der Ball eine größere Y-Koordinate als 19 hat (wird noch klar wieso) und ich im Menü:

Spiel->Modus->Einzelspieler

drücke, wird die Paint Methode aufgerufen, der Grundriss des Spielfelds auf das PaintEventArg e der PictureBox gezeichnet, der Klasse des Balls mit einer Methode das PaintEventArg e übergeben, dann wird der aktuelle Stand (Spiel gestartet oder nicht) geprüft.

Wenn das Spiel gestartet ist, wird der Ball gezeichnet, sowie die beiden Schläger/Spieler.

Danach wird der TimerTick aufgerufen. Dort werden Labels geschrieben und im Anschluss wird die Methode ball->move(); ausgeführt. Wenn ich dort mit dem Debugger einsteige und mir das am Anfang übergebene PaintEventArg e ansehe, sehe ich eine breite von 21px und eine höhe von 19px (Angaben zur PictureBox), welche aber 600px und 400px sein sollten.

Dadurch wird in der ball->move() Methode (die im Timer ausgeführt wird) ein Event ausgelöst, dass der Ball den oberen oder unteren Rand berührt hat und die horizontale Richtung gewechselt wird (passiert nur wenn die Y-Koordinate des Balls > 19 ist).

Dann gehe ich im Debug einen TimerTick weiter an die selbe Stell (wo ich dann nicht das Menü verwendet habe) und siehe da, Höhe = 400; Breite = 600 und alles wunderbar.

Der Ball hat jedoch trotzdem den Tick davor die horizontale Richtung gewechselt.

Lässt sich beliebig oft nachstellen.

Grund:

Der GC gibt die Ressourcen der PictureBox wieder frei und löscht sie aus dem Arbeitsspeicher (auf den ich noch verweise wegen dem übergebenen PaintEventArg e), ohne dass ich das möchte. Somit MUSS ich das unterbinden und die Freigabe der Ressourcen selbst übernehmen.

Das ist Unsinn, es gibt keine zu lange Lebensdauer für ein Control und der Garbage Collector räumt Objecte nur auf wenn diese nicht mehr referenziert werden.

Sorry...hatte mich vertan...meinte genau das gegenteil...sprich dass die Lebensdauer (Verfügbarkeitszeit) der angezeigten PictureBox zu kurz ist um nach Ansprechen des Menüs (was übrigens nichts bewirkt, da nur etwas passiert, wenn das Spiel nicht gestartet ist) alle weiteren Schritte auf der PictureBox abzubilden.

Ich hoffe, dass das etwas verständlicher und ausführlich genug war

Geschrieben
Eben nicht! Der GC macht es viel zu früh.

[...]

Wenn ich dort mit dem Debugger einsteige und mir das am Anfang übergebene PaintEventArg e ansehe, sehe ich eine breite von 21px und eine höhe von 19px (Angaben zur PictureBox), welche aber 600px und 400px sein sollten.

[...]

Dann gehe ich im Debug einen TimerTick weiter an die selbe Stell (wo ich dann nicht das Menü verwendet habe) und siehe da, Höhe = 400; Breite = 600 und alles wunderbar.

Das klingt mehr nach mehrfacher Instanziierung. hmm

Grund:

Der GC gibt die Ressourcen der PictureBox wieder frei und löscht sie aus dem Arbeitsspeicher (auf den ich noch verweise wegen dem übergebenen PaintEventArg e), ohne dass ich das möchte. Somit MUSS ich das unterbinden und die Freigabe der Ressourcen selbst übernehmen.

Vielleicht hilft das ja:

GC.Collect Method (System)

GC.WaitForPendingFinalizers Method (System)

Geschrieben

Wie bereits gesagt gibt der GC Objekte nur frei wenn diese nicht mehr referenziert werden und nicht einfach mal so weil er gerade Lust dazu hat ;)

Ohne entsprechenden Code lässt sich aber nur raten wo das Problem liegen könnte. Woher kommt die PictureBox? Hast du die im Designer auf deine Form gezogen oder wird die zur Laufzeit erstellt?

Auch die Aussage das das klicken auf das Menü nichts bewirkt kann so nicht stimmen denn wenn es so wäre würde ja nichts passieren. Also muss hier irgendwo der Fehler liegen...

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...