[C#] Application.EnableVisualStyles() & Application.DoEvents() -> hoher Speicherverbrauch
-
Frickler!
-
Hellsgore schrieb:
baust du dir einen Thread um z.B. eine ListView zu füllen oder um einen Fortschrittsbalken laufen zu lassen?
Salut,
klar, ich weiß jedenfalls nicht, was an
{ Thread thread=new Thread(new ThreadStart(myFunc)); thread.Start(); }
komplex ist...
Es gehört zu gutem (professionellem) Programmierstil, sog. "Worker Threads" für langfrisitige Aufgaben zu verwenden, damit der Hauptthreaad sich um die GUI (und damit um die Benutzeraus- und eingaben) kümmern kann.
-
Ich verstehe nicht, wie du deswegen grundsätzlich auf DoEvents() verzichten kannst. Falls du lediglich meinst, man sollte nicht auf dem Main-Thread ne Stunde arbeiten und ab und zu mit DoEvents() reagieren, hast du für die meisten Fälle Recht, aber das macht noch lange nicht eine der beiden Methoden überflüssig. Manchmal will ich ein blockierendes Warten auf eine Message und manchmal will ich peeken, jedes für sein Anwendungszweck.
In einer Game-Loop wäre es Bullshit, unterm Rendern in einem anderen Thread ein Event abzuarbeiten, was das Fenster minimiert, oder während der Logikberechnung User-Input für Einheitenbefehle entgegen zu nehmen. Ein immer horchender Thread verhält sich nicht deterministisch, aber manchmal braucht man das.
-
Optimizer schrieb:
aber das macht noch lange nicht eine der beiden Methoden überflüssig.
Bahnhof? DoEvents() ist eine Funktion. Sie zu verwenden, ist generell schlechte Praxis, die mit vielen Nachteilen, z. B. fehleranfälligem Spaghetti-Code behaftet ist. Deshalb nennt man ihre Verwendung auch "Call of the Devil", weil da schon viele stunden- bzw. tagelang nach Fehlern in ihrem Code gesucht haben.
Optimizer schrieb:
Manchmal will ich ein blockierendes Warten auf eine Message und manchmal will ich peeken, jedes für sein Anwendungszweck.
Das alles gibt's bei .NET nicht mehr. Message-Loops sind in die Interna von .NET verbannt worden. .NET-Programmierung (wie die VB-Programmierung generell) nennt man auch "Ereignisgesteuerte Programmierung", da man hier nur noch auf vorgefertigte Ereignisse reagiert, die vom Framework bereitgestellt werden.
Optimizer schrieb:
In einer Game-Loop wäre es Bullshit, unterm Rendern in einem anderen Thread ein Event abzuarbeiten, was das Fenster minimiert, oder während der Logikberechnung User-Input für Einheitenbefehle entgegen zu nehmen. Ein immer horchender Thread verhält sich nicht deterministisch, aber manchmal braucht man das.
Sehe ich nicht so. Jeder Thread hat seine Aufgabe, das ist strukturiert und gut so. Solange für den GUI-Thread kein Ereignis vorliegt, schläft der tief und fest und frisst auf keine Ressourcen. Wenn aber ein GUI-Ereignis eintritt, gibt's was zu tun, und das ist dann ja wohl auch seine Aufgabe.
Gruß,
Axel
-
Sportboot schrieb:
Optimizer schrieb:
aber das macht noch lange nicht eine der beiden Methoden überflüssig.
Bahnhof? DoEvents() ist eine Funktion. Sie zu verwenden, ist generell schlechte Praxis, die mit vielen Nachteilen, z. B. fehleranfälligem Spaghetti-Code behaftet ist. Deshalb nennt man ihre Verwendung auch "Call of the Devil", weil da schon viele stunden- bzw. tagelang nach Fehlern in ihrem Code gesucht haben.
Ich habe gesagt, dass keine dieser beiden Funktionen überflüssig ist, auch DoEvents nicht. Call of the devil sagen nur Leute, die nicht wissen, was man wann einsetzt.
Optimizer schrieb:
Manchmal will ich ein blockierendes Warten auf eine Message und manchmal will ich peeken, jedes für sein Anwendungszweck.
Das alles gibt's bei .NET nicht mehr. Message-Loops sind in die Interna von .NET verbannt worden. .NET-Programmierung (wie die VB-Programmierung generell) nennt man auch "Ereignisgesteuerte Programmierung", da man hier nur noch auf vorgefertigte Ereignisse reagiert, die vom Framework bereitgestellt werden.
Das macht keinen Unterschied zu Windows-Events. Es geht hier einzig und allein um die Frage, ob ich deterministische Zeitpunkte für die Ereignisbehandlung brauche oder nicht. DoEvents() ist while( peek() ); und Run() ist while( true ) get(); Es ist nichts revolutionäres dabei.
Das gibt's jetzt alles nicht mehr, jaja. Messages werden jetzt so behandelt, dass die Message-Loop Ereignisse auslöst, WOW!Wie du weiter oben siehst, kann man mit 20 Code-Zeilen diese "Revolution" selber implementieren.
Optimizer schrieb:
In einer Game-Loop wäre es Bullshit, unterm Rendern in einem anderen Thread ein Event abzuarbeiten, was das Fenster minimiert, oder während der Logikberechnung User-Input für Einheitenbefehle entgegen zu nehmen. Ein immer horchender Thread verhält sich nicht deterministisch, aber manchmal braucht man das.
Sehe ich nicht so. Jeder Thread hat seine Aufgabe, das ist strukturiert und gut so.
Das ist fantastisch, aber ich brauche in einer Game-Loop determinitische Ereignisbehandlung und nicht jeden Thread für eine Aufgabe, sonst muss ich regelmäßig (2398742mal pro Frame) ein paar wichtige Datenstrukturen locken, weil sie von zwei Threads beschrieben werden. Ui, das wird teuer, so teuer, dass man nen doppelt so dicken Rechner braucht. Und was ist der Gewinn? Gar nichts, am Ende ist es wieder synchronisiert, so wie ich es auch hätte, wenn ich DoEvents() zu deterministischen Zeitpunkten aufrufe.
Nochmal extra langsam: Ich darf Befehle vom Spieler nicht mitten in irgendwelchen Berechnungen ausführen, sondern muss auf bestimmte Zeitpunkte warten. So lange würde mein Run()-Thread alle Events queuen und ich leer die Queue dann irgendwann. Schaun wir uns mal an, was man mit DoEvents() macht: Man queuet alle Ereignisse (indem man sie sich nicht holt, werden sie gequeuet) und mit DoEvents() hole ich sie mir alle auf einmal zum gewünschten Zeitpunkt.
Solange für den GUI-Thread kein Ereignis vorliegt, schläft der tief und fest und frisst auf keine Ressourcen. Wenn aber ein GUI-Ereignis eintritt, gibt's was zu tun, und das ist dann ja wohl auch seine Aufgabe.
DoEvents() frisst in einer Game-Loop auch nichts, wie du dir sicher ganz leicht vorstellen kannst, wird in einer Game-Loop nicht auf Ereignisse gewartet, sondern da wird immer was gemacht. Auslastung 100%. Ein "GUI-Thread" ist fürn Arsch, ich warte nicht, dass der Mensch mit seinen biologischen 0.2 Hz was macht, sondern ich arbeite ununterbrochen unter Vollast. Der Fettsack vorm Schirm will 200fps und nicht nur was sehen, wenn er die Maus bewegt.
-
Jetzt bleib mal auf dem Teppich! Hat dich einer angegriffen? Oder willst du nur deine Meinung um jeden Preis verteidigen?
Optimizer schrieb:
Ich habe gesagt, dass keine dieser beiden Funktionen überflüssig ist, auch DoEvents nicht. Call of the devil sagen nur Leute, die nicht wissen, was man wann einsetzt.
Das ist deine Meinung. Du kannst dir sicher vorstellen, dass es - außer dir - Programmier gibt, die sich mit Programmierung auskennen und trotzdem die Nachteile der einen oder anderen Funktion (er)kennen.
Optimizer schrieb:
WOW!
Wie du weiter oben siehst, kann man mit 20 Code-Zeilen diese "Revolution" selber implementieren.
Konnte..! Heutzutage macht man das mit einer Zeile. Ich überlasse dir die Beurteilung, was effizienter ist.
Optimizer schrieb:
aber ich brauche in einer Game-Loop determinitische Ereignisbehandlung und nicht jeden Thread für eine Aufgabe, sonst muss ich regelmäßig (2398742mal pro Frame) ein paar wichtige Datenstrukturen locken, weil sie von zwei Threads beschrieben werden.
Dann machst du etwas in deinem Design falsch.
Optimizer schrieb:
Nochmal extra langsam: Man queuet alle Ereignisse (indem man sie sich nicht holt, werden sie gequeuet) und mit DoEvents() hole ich sie mir alle auf einmal zum gewünschten Zeitpunkt.
Kann natürlich nicht jeder so ein Schnelldenker sein wie du ;), aber hast du dir schon einmal Gedanken darüber gemacht, dass du dir mit DoEvents() auch Rat-Race-Probleme einhandeln kannst?
Optimizer schrieb:
DoEvents() frisst in einer Game-Loop auch nichts, wie du dir sicher ganz leicht vorstellen kannst, wird in einer Game-Loop nicht auf Ereignisse gewartet, sondern da wird immer was gemacht. Auslastung 100%. Ein "GUI-Thread" ist fürn *****, ich warte nicht, dass der Mensch mit seinen biologischen 0.2 Hz was macht, sondern ich arbeite ununterbrochen unter Vollast. Der Fettsack vorm Schirm will 200fps und nicht nur was sehen, wenn er die Maus bewegt.
Du wirst lachen, das kann ich mir vorstellen. Das ist dann ja übrigens die typische Aufgabe eines Worker-Threads. Kennst du nichts von, ich weiß. Aber vielleicht liest du erstmal ein bisschen und wir reden dann noch einmal? Hmm?
-
Sportboot schrieb:
Jetzt bleib mal auf dem Teppich! Hat dich einer angegriffen? Oder willst du nur deine Meinung um jeden Preis verteidigen?
Höh, ich habe doch keinen beleidigt, außer fiktive Personen, oder? Nein, ich will meine Meinung nicht um jeden Preis verteidigen, ich habe Recht.
Optimizer schrieb:
Ich habe gesagt, dass keine dieser beiden Funktionen überflüssig ist, auch DoEvents nicht. Call of the devil sagen nur Leute, die nicht wissen, was man wann einsetzt.
Das ist deine Meinung. Du kannst dir sicher vorstellen, dass es - außer dir - Programmier gibt, die sich mit Programmierung auskennen und trotzdem die Nachteile der einen oder anderen Funktion (er)kennen.
Hat doch nie einer gesagt, dass DoEvents() ohne Nachteil ist. Zum Glück haben aber die anderen Programmierer, die sich mit Programmierung auskennen, - außer mir - entschieden, dass man sowas auch braucht. Denn auch Run() hat Nachteile, andere Nachteile, z.B. nicht-Determinismus. Deshalb hat ja der Optimizer ganz vorsichtig formuliert: "jedes für seinen Anwendungszweck"
Optimizer schrieb:
WOW!
Wie du weiter oben siehst, kann man mit 20 Code-Zeilen diese "Revolution" selber implementieren.
Konnte..! Heutzutage macht man das mit einer Zeile. Ich überlasse dir die Beurteilung, was effizienter ist.
Wo ist denn dein Problem? Ich habe nur gesagt, dass gar nichts unglaublich runderneuert ist, wie du es dargestellt hast, sondern dass lediglich ein dünner Wrapper um die Message-Loop vorhanden ist.
Optimizer schrieb:
aber ich brauche in einer Game-Loop determinitische Ereignisbehandlung und nicht jeden Thread für eine Aufgabe, sonst muss ich regelmäßig (2398742mal pro Frame) ein paar wichtige Datenstrukturen locken, weil sie von zwei Threads beschrieben werden.
Dann machst du etwas in deinem Design falsch.
Du hast keine Ahnung.
Optimizer schrieb:
Nochmal extra langsam: Man queuet alle Ereignisse (indem man sie sich nicht holt, werden sie gequeuet) und mit DoEvents() hole ich sie mir alle auf einmal zum gewünschten Zeitpunkt.
Kann natürlich nicht jeder so ein Schnelldenker sein wie du ;), aber hast du dir schon einmal Gedanken darüber gemacht, dass du dir mit DoEvents() auch Rat-Race-Probleme einhandeln kannst?
Ich bin mir über viele mögliche Probleme im Klaren, auch über die, die Run() in diesem Fall bringen würde.
Optimizer schrieb:
DoEvents() frisst in einer Game-Loop auch nichts, wie du dir sicher ganz leicht vorstellen kannst, wird in einer Game-Loop nicht auf Ereignisse gewartet, sondern da wird immer was gemacht. Auslastung 100%. Ein "GUI-Thread" ist fürn *****, ich warte nicht, dass der Mensch mit seinen biologischen 0.2 Hz was macht, sondern ich arbeite ununterbrochen unter Vollast. Der Fettsack vorm Schirm will 200fps und nicht nur was sehen, wenn er die Maus bewegt.
Du wirst lachen, das kann ich mir vorstellen. Das ist dann ja übrigens die typische Aufgabe eines Worker-Threads. Kennst du nichts von, ich weiß. Aber vielleicht liest du erstmal ein bisschen und wir reden dann noch einmal? Hmm?
Du kapierst nicht, dass ich nicht zu jedem beliebigen Zeitpunkt einen Befehl, der von User-Input ausgeht, ausführen kann. Es ist ein Unterschied, ob man die Ereignisbehandlung für einen 3D-Shooter oder für ein Textverarbeitungsprogramm schreibt.
Wenn ich gerade mehrere Millisekunden lang einen Weg für eine Einheit berechne ist es nicht unwahrscheinlich, dass währenddessen vom Benutzer ein neuer Befehl gegeben wird, mit dem Ergebnis, dass ein anderer Thread auf das selbe Einheiten-Objekt zugreift und mitten in meiner Berechnung mir irgendwelche Zustände (z.B. Informationen über den Zielort) ändert. Das kann ich nur durch locken verhinden und mehrere hundert male sinnlos zu locken, damit ich, ohne jeden Vorteil, die Ereignisbehandlung in einem eigenen Thread habe, bietet sich nicht an (EDIT: eine Alternative wäre natürlich, wie schon erwähnt, im Event-Thread die Ereignisse nur anzusammeln, aber das ist dann nicht mehr wirklich was anderes, als DoEvents() mit mehr Aufwand und Overhead). Die meisten Spiele sind single-threaded programmiert, wenn man von Sound und Netzwerk absieht. Wenn überhaupt multithreading ins Spiel kommt, dann höchstens noch eine Trennung von Logik und Grafikdarstellung aber sicher nicht, um während einer Logik-Berechnung irgendwie fies was wegzuändern, weil der User einen Klick gemacht hat.
Mach mal ein Spiel und zwar kein Kartenspiel, dass auf User-Input wartet. Ich muss mir nicht neues Wissen aneignen, um mit dir darüber reden zu können, denn ich weiß, wann ich welche der beiden Vorgehensweisen brauche, so wie Micrsoft es weißt, so wie du es nicht weißt, weil du denkst, dass DoEvents() völlig unnötig eingebaut worden ist.
-
Für Spiele würd ich OnIdle (keine Ahnung ob das so heißt) vorschlagen.
-
idle schrieb:
Für Spiele würd ich OnIdle (keine Ahnung ob das so heißt) vorschlagen.
falsch
-
Optimizer schrieb:
Nein, ich will meine Meinung nicht um jeden Preis verteidigen, ich habe Recht.
Sicher...
Optimizer schrieb:
Deshalb hat ja der Optimizer ganz vorsichtig formuliert: "jedes für seinen Anwendungszweck"
Dem stimme ich zu.
Optimizer schrieb:
Wo ist denn dein Problem? Ich habe nur gesagt, dass gar nichts unglaublich runderneuert ist, wie du es dargestellt hast, sondern dass lediglich ein dünner Wrapper um die Message-Loop vorhanden ist.
Habe ich nicht. Wo? Ist mir schon klar, das das ein Wrapper ist. Wo habe ich von Revolution gesprochen? Du reflektierst das ziemlich krass..
Optimizer schrieb:
Du hast keine Ahnung.
Das kannst du gerne denken, du Held.
Optimizer schrieb:
Ich bin mir über viele mögliche Probleme im Klaren, auch über die, die Run() in diesem Fall bringen würde.
Ich sehe, wir kommen hier nicht weiter. Ich will und muss dich nicht überzeugen. Mach's wie du willst.
Optimizer schrieb:
Wenn ich gerade mehrere Millisekunden lang einen Weg für eine Einheit berechne ist es nicht unwahrscheinlich, dass währenddessen vom Benutzer ein neuer Befehl gegeben wird, mit dem Ergebnis, dass ein anderer Thread auf das selbe Einheiten-Objekt zugreift und mitten in meiner Berechnung mir irgendwelche Zustände (z.B. Informationen über den Zielort) ändert. Das kann ich nur durch locken verhinden und mehrere hundert male sinnlos zu locken... bla
Was du übersiehst ist, dass DoEvents() alle Events ausführt, nicht nur die die du gerade abarbeiten willst. Queues verwendet man, indem man Queues implementiert, nicht indem man wild DoEvents() aufruft. Das ist sauber, das g'hört so und das ist - wenn man's geschickt macht - auch schnell. DoEvents() stammt aus alten Windows 3.11-Zeiten, als Windows noch nicht multithreading-fähig war. Und es gibt halt immer Programmierer, die es sich leicht machen, und deshalb ist DoEvents() halt immer noch drin. Genauso wie die Verarbeitung der A20-Leitung. Für die gibt's auch keine Daseinsberechtigung mehr.
Aber wie gesagt, ich werde müde, mit dir darüber zu diskutieren. Mein Vorschlag: lesen. Gibt genügend Quellen.
-
In irgendnem Blog von nem microsoft-menschen steht auch geschrieben, das für manche Dinge nen Thread einfach völliger Overkill wäre und genau deswegen DoEvents überhaupt erst bei dotnet Einzug gefunden hat.
Gerade bei Spielen wäre es ein enormer Aufwand einen Extra-Thread zu benutzen und die Mühe wird dazu auch noch mit ein wenig Performance-Verlust belohnt.
-
@Sportboot:
Erst stimmst du mir zu, dass beide Möglichkeiten ihren Anwendungsbereich haben und dann schreibst du. Es gibt für DoEvents() keine Daseinsberechtigung mehr. So viel Konsequenz überzeugt.Was du übersiehst ist, dass DoEvents() alle Events ausführt, nicht nur die die du gerade abarbeiten willst.
lol, Application.Run() auch. Und das auch noch zu einem unbestimmten Zeitpunkt Du bist kurz davor, dich zu disqualifizieren. Es gibt keinen Unterschied darin, welche Events ausgelöst werden.
Der Unterschied ist, dass bei Run die Nachrichten getted, also eine blockierende Lese-Operation ist, während DoEvents() peekt. Ich habe dir auch schon 2mal jetzt erklärt, dass man manchmal das eine braucht und manchmal das andere.Queues verwendet man, indem man Queues implementiert, nicht indem man wild DoEvents() aufruft.
Es ist bereits eine Queue implementiert, die nennt sich MessageQueue und wird von Run() ununterbrochen gelesen, was praktisch ist, wenn ich gar keine Queue will. Und wenn ich eine will, werde ich sicher nicht eine Queue ununterbrochen auslesen um die Ereignisse dann in meine eigene Queue zu stopfen. Das wäre nicht trivial, weil ich eigentlich gar nicht verhindern kann, dass Run() die Events zu einem mir nicht genehmen Zeitpunkt auslöst und obendrein unglaublich hirnverbrannt.
DoEvents() stammt aus alten Windows 3.11-Zeiten, als Windows noch nicht multithreading-fähig war.
Damit hast du dich leider disqualifiziert.
-
@Optimizer
Optimizer schrieb:
lol, Application.Run() auch.
Das habe ich mir gedacht, dass das jetzt kommt. Aber im Gegensatz zu DoEvents() kann bei einer optimierten Prozessorarchitektur der GUI-Thread den Worker-Thread nicht (bzw. nicht so stark) ausbremsen.
Optimizer schrieb:
Es ist bereits eine Queue implementiert, die nennt sich MessageQueue und wird von Run() ununterbrochen gelesen, was praktisch ist, wenn ich gar keine Queue will. Und wenn ich eine will, werde ich sicher nicht eine Queue ununterbrochen auslesen um die Ereignisse dann in meine eigene Queue zu stopfen. Das wäre nicht trivial, weil ich eigentlich gar nicht verhindern kann, dass Run() die Events zu einem mir nicht genehmen Zeitpunkt auslöst und obendrein unglaublich hirnverbrannt.
Du verstehst es nicht. Und du verwechselst Windows-Messages mit programminternen Informationen.
Ich weiß eh nicht, warum ich mit dir über Spieleprogrammierung unter .NET diskutiere. Das schon ist ein Widerspruch in sich, da .NET gerade eben wegen des ganzen Überbaus gar nicht effizient genug für schnelle Spiele ist. Bist du sicher, dass du hier überhaupt richtig bist?
Optimizer schrieb:
DoEvents() stammt aus alten Windows 3.11-Zeiten, als Windows noch nicht multithreading-fähig war.
Damit hast du dich leider disqualifiziert.
Und jetzt hast du keine Ahnung. Schau bitte selbst nach und finde DoEvents() in der Makro-Implementation von Access. Dort wurde der Befehl eingeführt.
@geeky
Wie ich bereits relativ weit vorne geschildert habe, ist ein Thread kein Overkill, sondern leicht zu implementieren.Ich möchte das jetzt ein letztes Mal klar stellen: Niemand hält euch davon ab, DoEvents() zu benutzen, wahrscheinlich seid Ihr eh die einzigen, die Euren Code jemals zu Gesicht bekommen. - Mir ist es egal, und solange es funktioniert spricht nichts dagegen. Aber die Nachteile von Threads, die Optimizer hier anführt, sind schlicht sachlich falsch. Ich schreibe hier nur noch für's Protokoll. Jeder, der diesen Thread später einmal liest, soll sich selbst ein Bild machen und eine Entscheidung treffen können.
Noch ein Wort zu Optimizer: Ich will nicht mit dir streiten. Dafür ist meine Zeit zu schade. Überdenke einfach einmal deinen Standpunkt. qed
-
Sportboot schrieb:
@Optimizer
Optimizer schrieb:
lol, Application.Run() auch.
Das habe ich mir gedacht, dass das jetzt kommt.
Klar kommt das. Weil es einfach nicht richtig war, zu erwähnen, dass DoEvents() Ereignisse auslöst, die mich nicht interessieren und dabei zu verschweigen, dass es bei Run() nicht anders ist.
Aber im Gegensatz zu DoEvents() kann bei einer optimierten Prozessorarchitektur der GUI-Thread den Worker-Thread nicht (bzw. nicht so stark) ausbremsen.
Nicht wenn ich synchronisieren muss, aber das ist schon seit 2 Tagen nicht bei dir angekommen und wird es um diese Uhrzeit wohl auch nicht mehr. Besonders lustig finde ich ja, dass du hier mit Performance kommst, wo doch bei einer "ruhigen" GUI-Anwendung die Ereignisbehandlung selten ein Flaschenhals sein sollte. Mir ging es jedenfalls nicht mal um Performance (obwohl auch in diesem Punkt für beschriebene Problemstellung DoEvents() überlegen ist), sondern um Probleme bei der Synchronisation.
Optimizer schrieb:
Es ist bereits eine Queue implementiert, die nennt sich MessageQueue und wird von Run() ununterbrochen gelesen, was praktisch ist, wenn ich gar keine Queue will. Und wenn ich eine will, werde ich sicher nicht eine Queue ununterbrochen auslesen um die Ereignisse dann in meine eigene Queue zu stopfen. Das wäre nicht trivial, weil ich eigentlich gar nicht verhindern kann, dass Run() die Events zu einem mir nicht genehmen Zeitpunkt auslöst und obendrein unglaublich hirnverbrannt.
Du verstehst es nicht. Und du verwechselst Windows-Messages mit programminternen Informationen.
Na sowas!
Also ich habe den Leuten früher immer geraten, nicht mehr das Windows-API zu lernen, weil es für das Verständnis von .Net nicht wichtig sei, aber ich sehe, das muss ich jetzt revidieren.Optimizer schrieb:
DoEvents() stammt aus alten Windows 3.11-Zeiten, als Windows noch nicht multithreading-fähig war.
Damit hast du dich leider disqualifiziert.
Und jetzt hast du keine Ahnung. Schau bitte selbst nach und finde DoEvents() in der Makro-Implementation von Access. Dort wurde der Befehl eingeführt.
Ich schaue bestimmt nicht irgendwas von Access nach, weil mich das einen feuchten Irgendwas interessiert. Ich schaue in die MSDN, was DoEvents() in .Net macht (was übrigens das selbe ist, was es seit VB macht) und siehe da, es ist das, was ich brauche.
Noch ein Wort zu Optimizer: Ich will nicht mit dir streiten. Dafür ist meine Zeit zu schade. Überdenke einfach einmal deinen Standpunkt. qed
Mein Standpunkt ist wesentlich toleranter als deiner, es geht mir ja nicht wie dir um Run() vs. DoEvents(), sondern um die Eignung. Du hast noch kein Programm geschrieben, wo du die von mir genannten Anforderungen hast und für 99% der GUI-Programme ist Run() die richtige Wahl. Das ändert freilich nichts daran, dass bei 1% der Software eine andere Ereignisbehandlung nötig oder zumindest sinnvoll ist. Da du vermutlich nicht beim Design des .Net Frameworks mitwirkst, ist es aber sinnlos, dich überzeugen zu wollen, wenn du auf deinen extremen Standpunkt beharrst. Die richtige Entscheidung, beide Möglichkeiten zur Abarbeitung der Event-Queue anzubieten, wurde bereits getroffen, von (wie du sehr gerne betonst) Leuten, die außer mir auch noch kompetent sind.
-
~TRED CLOSED~
(Sportboot hat aber Recht)
-
In Spielen ist es doch so das man guckt ob eine Nachricht vorhanden ist, wenn ja ruft man DispatchMessage auf, ansonsten wird halt alles nötige für das Spiel gemacht!
DoEvents bearbeitet aber alle Nachrichten die in der Queue sind und nicht nur Eine.
-
Game Loop schrieb:
In Spielen ist es doch so das man guckt ob eine Nachricht vorhanden ist, wenn ja ruft man DispatchMessage auf, ansonsten wird halt alles nötige für das Spiel gemacht!
DoEvents bearbeitet aber alle Nachrichten die in der Queue sind und nicht nur Eine.
im buch von david scherfgen wird es aber anders gezeigt, und zwar so:
while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&Message); DispatchMessage(&Message); } MoveGame(); RenderGame();
und die obere schleife entspricht ja einem DoEvents. also ich würd sagen optimizer liegt richtig.
wobei ich aber sagen würde das es sonst kaum eine sinnvolle anwendung für DoEvents gibt.
-
hier noch'n schöner link über DoEvents http://blogs.msdn.com/jfoscoding/archive/2005/08/06/448560.aspx
-
Game Loop schrieb:
In Spielen ist es doch so das man guckt ob eine Nachricht vorhanden ist, wenn ja ruft man DispatchMessage auf, ansonsten wird halt alles nötige für das Spiel gemacht!
DoEvents bearbeitet aber alle Nachrichten die in der Queue sind und nicht nur Eine.
Zusätzlich zu dem was unreg gesagt hat, würde ich vermuten, dass beides auf das Selbe hinaus läuft. Bei 100fps wird nie mehr als eine Nachricht in der Queue sein, meistens gar keine.