Laden...

Fenster laufend neu zeichnen, ohne 100% CPU-Last zu erzeugen

Erstellt von Tsuyo vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.906 Views
T
Tsuyo Themenstarter:in
20 Beiträge seit 2010
vor 13 Jahren
Fenster laufend neu zeichnen, ohne 100% CPU-Last zu erzeugen

Moin, ich schreibe gerade ein kleines Programm das mit Gdi arbeitet, das wird in einem Backgroundworker per while immerwieder wiederholt.
Jedoch nimmt dafür mein Programm mehr als 50% (Laut Taskmamanger) meines Cpu's ein. Und das soll natürlich nicht sein, woran kann das liegen? Gibts Tools die das Programm analysieren können und sagen wo und was so oft ausgeführt wird?

grüße

61 Beiträge seit 2009
vor 13 Jahren

Hallo Tsuyo,

ich weiß zwar nicht, ob ich da den richtigen Ansatz habe, aber auf jeden Fall kann es helfen, wenn man sowas vermeidet:


     // nicht so
     while(nothingToDo)
          continue;

besser ist dabei sowas zu machen:


     // besser so
     while(nothingToDo)
          System.Threading.Thread.Sleep(0);

Ich kenne zwar deinen Code nicht, aber vielleicht hilft die dieser Ansatz schon.
Wenn ich nur continue verwende, dann läuft der Prozess eventuell mit voller Leistung und versucht so schnell er kann (und so oft wie möglich), diese Schleife zu durchlaufen.
Manmal verwendet man System.Threading.Thread.Sleep um den Thread warten zu lassen und dann wäre der Wert sicher größer als 0.
Falls man aber nur dem System singnalisieren möchte, dass jetzt erstmal die anderen Threads weitermachen können (weil er ja gerade nicht so viel zu tun hat), dann ist der Wert 0 entscheidend. Die Pause begrenzt sich also auf die laufenden Prozesse im System und so kann eventuell unnütz verbrauchte Leistung für diesen Prozess oder Thread mindern. Besonders bei Schleifen 😉

In der Zeit vor fünf Minuten ist Jetzt die Zukunft. Jetzt ist die Gegenwart. Die Zeit, in der ich zu erzählen begonnen habe, ist die Vergangenheit von Jetzt und die Zukunft von der Gegenwart der Zeit, fünf Minuten bevor ich zu erzählen begann.

5.742 Beiträge seit 2007
vor 13 Jahren

@Ruben: Thread.Sleep ist genauso verkehrt. Besser ist auf jeden Fall ein Timer oder spezielle Synchronisationsobjekte (z.B. _WaitHandle_s etc.)

Programme zum "Resourcenfresser-Finden" heißen Profiler. Google einfach mal danach.

Eventuell lässt sich aber schon am grundsätzlichen Aufbau deiner Anwendung etwas verbessern - "das wird in einem Backgroundworker per while immerwieder wiederholt." klingt irgendwie suboptimal. Poste mal etwas Code.

T
Tsuyo Themenstarter:in
20 Beiträge seit 2010
vor 13 Jahren

Hi, danke schonmal für die Antworten.
Der Backgroundworker macht nichts anderes als das:


        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true) {
                try { 
					device.DoUpdateAndDraw();
                }
                catch (Exception) {                
                }
            }
        }

Damit lade ich ein Bild auf ein LCDbildschirm.

grüße

/Edit:
Scheint wohl die Dll zu sein die soviel frisst Oo Wenn ich DoUpdateAndDraw() auskommentiere ist die CPU immer auf 0.
Externe "LibFixes" Gibts wohl nicht oder?

/Edit²:
Okay, es war doch nicht die Lib, wenn ich ein Sleep in die While mache, ist die CPU immer auf 0. Kann mir jemand erklären wieso?

D
67 Beiträge seit 2009
vor 13 Jahren

Dir ist schon klar das das ne endlosschleife ist.

sobald die Methode DoUpdateAndDraw fertig ist wird sie wieder aufgerufen

T
Tsuyo Themenstarter:in
20 Beiträge seit 2010
vor 13 Jahren

Klar weiss ich das, muss ja auch sein, sonst wird ja nicht aufs Display gezeichnet.

5.941 Beiträge seit 2005
vor 13 Jahren

Salute Tsuyo

Die Benutzung von "device" sieht sehr nach einem invaliden Crossthreadzugriff aus, wenn "device" eine Instanzvariable ist.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

61 Beiträge seit 2009
vor 13 Jahren

Dir ist schon klar das das ne endlosschleife ist.

sobald die Methode DoUpdateAndDraw fertig ist wird sie wieder aufgerufen

Ich denke DaemNice meint damit, dass dieser Prozess von außen niemals abgebrochen werden kann... also endlos ist. Aber ich hoffe, dass das nur in dem Beispiel so ist. 🙂

/Edit²:
Okay, es war doch nicht die Lib, wenn ich ein Sleep in die While mache, ist die CPU immer auf 0. Kann mir jemand erklären wieso?

Mehr als das bisher gesagte, kann ich dazu leider auch nicht sagen ^^.

Damit lade ich ein Bild auf ein LCDbildschirm.

Vielleicht hilft es die Anzahl der Bilder pro Sekunde zu steuern als das über diese Schleife die Bilder so schnell aktualisiert werden, wie Leistung des Prozessors es schaffen kann.
Mit GPU und Bildausgabe kenne ich mich nur leider nicht so aus.

In der Zeit vor fünf Minuten ist Jetzt die Zukunft. Jetzt ist die Gegenwart. Die Zeit, in der ich zu erzählen begonnen habe, ist die Vergangenheit von Jetzt und die Zukunft von der Gegenwart der Zeit, fünf Minuten bevor ich zu erzählen begann.

C
401 Beiträge seit 2007
vor 13 Jahren

Okay, es war doch nicht die Lib, wenn ich ein Sleep in die While mache, ist die CPU immer auf 0. Kann mir jemand erklären wieso?

Ja, wenn du nicht wartest, dann wird durchgehend neu gezeichnet. Es reicht bei weitem, wenn du 60 mal pro Sekunde zeichnest. Benutze dafür am besten einen Timer.

Gruß

Dario

T
Tsuyo Themenstarter:in
20 Beiträge seit 2010
vor 13 Jahren

Alles klar 😉

Danke für die hilfreichen Antworten!