Re: Problem GUI-Loop-CPU Auslastung
From: Frank Dzaebel (Post_at_FranksSeite.de)
Date: 03/03/05
- Next message: Rainer Queck: "alles INI oder was?"
- Previous message: Frank Dzaebel: "Re: ListBox Problemchen"
- In reply to: Olli Goessler: "Problem GUI-Loop-CPU Auslastung"
- Next in thread: Olli Goessler: "Re: Problem GUI-Loop-CPU Auslastung"
- Reply: Olli Goessler: "Re: Problem GUI-Loop-CPU Auslastung"
- Messages sorted by: [ date ] [ thread ]
Date: Fri, 4 Mar 2005 00:01:55 +0100
Hallo Olli,
> Mit einem Button auf der Mainform werfe ich den Loop an. Dieser arbeitet
> bis zum beenden und liefert mir meine Counter. Waehrend des loops ist
> meine CPU-Auslastung ca. bei 2-4 %. Klicke ich nur einmal die Form direkt
> an (z.B. Titelbar) oder verschiebe diese am Desktop und starte danach den
> Loop dann habe ich ploetzlich eine CPU-Auslastung nahe der 95%.
Also zunächst einmal ist es eine Standard-Einstellung für Windows-PCs, dass
diese ihre Vordergrund-Applikationen höher 'priorisieren' (intern über
Zeitscheiben-Quantum).
Dies kann auch verändert werden auf Hintergrund-Tasks, ist aber eine
System-weite Einstellung und ist auch OS-abhängig.
http://support.microsoft.com/kb/259025/en-us
Deswegen wird z.B. u.a. bei Klick-Aktivierung/Fenster-Verschiebung einer
Form normal die CPU-Usage für diesen Prozess und global höher.
[-> Process.PriorityBoostEnabled-Eigenschaft]
http://msdn.microsoft.com/library/deu/cpref/html/frlrfsystemdiagnosticsprocessclasspriorityboostenabledtopic.asp
Ein andere Sache ist Deine Loop.
Zwar wurde hier schon Application.DoEvents() vorgeschlagen, aber das ist oft
ein Workaround für eine sauberere Thread-Lösung.
Ich reisse das Thema mal oberflächlich an :
Im folgenden Beispiel werden 2 Threads gestartet. Der eine macht die Arbeit.
Der andere kümmert sich darum, dass Events verarbeitet werden, indem er
(ständig) den ersten suspended, Thread.Sleep(1) aufruft und dann den ersten
wieder resumed.
Dadurch wird die CPU-Usage des Gesamt-Prozesses sehr klein gehalten
(speziell Thread1).
(Die "TextBoxX.Text = Y" - Zeilen müßten eigentlich über InvokeRequired
aufgerufen werden)
Thread t1;
private void btnCpuUsage_Click(object sender, System.EventArgs e)
{
// DoHardWork(); // So (alleine würden keine Events verarbeitet)
t1 = new Thread(new ThreadStart(DoHardWork)); t1.Start();
new Thread(new ThreadStart(MessageThread)).Start();
}
private void MessageThread()
{
long count2 = 0;
while (!t1.IsAlive) Thread.Sleep(1);
while (t1.IsAlive)
{
if (t1.IsAlive) t1.Suspend();
Thread.Sleep(1);
if (t1.IsAlive) t1.Resume();
count2++ ;
}
textBox2.Text = "count2="+ count2.ToString() +
"\r\nEnded:" + DateTime.Now.ToLongTimeString();
}
private void DoHardWork()
{
Cursor = Cursors.WaitCursor;
long count1 = 0;
DateTime Start = DateTime.Now;
while ((DateTime.Now-Start).Seconds < 5)
{
Math.Sin(5.0d);
// if (count % 0xFFFF == 0) Thread.Sleep(1);
count1++ ;
}
Cursor = Cursors.Default;
textBox1.Text = "count1="+ count1.ToString() +
"\r\nStarted:" + Start.ToLongTimeString() +
", Ended:" + DateTime.Now.ToLongTimeString();
}
Dies wäre ein generischer Ansatz letztlich über OS-Time-Slicing.
Stattdessen kann auch innerhalb von DoHardWork() Thread.Sleep(1)
aufgerufen werden. Das wäre eine Verbesserung der Performance.
(Siehe die auskommentierte Zeile)
Übrigens benutzt auch die CLR selber letztlich Thread.Sleep(1) in
seinem Message-Dispatcher
(-> SystemEvents.WindowThreadProc: undokumentiert).
ciao Frank
-- Dipl.Inf. Frank Dzaebel [MCP C#] http://Dzaebel.NET
- Next message: Rainer Queck: "alles INI oder was?"
- Previous message: Frank Dzaebel: "Re: ListBox Problemchen"
- In reply to: Olli Goessler: "Problem GUI-Loop-CPU Auslastung"
- Next in thread: Olli Goessler: "Re: Problem GUI-Loop-CPU Auslastung"
- Reply: Olli Goessler: "Re: Problem GUI-Loop-CPU Auslastung"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|