PDA

Vollständige Version anzeigen : 100% Prozessorauslastung bei Warteschleife trotz DoEvents


schnarchzapfen
11.05.2004, 11:04
Hallo!
Ich verwende folgende kleine Prozedur um damit den Code bei Bedarf für eine bestimmte Anzahl von Sekunden anhalten zu können:

Sub Warten(AnzSekunden As Integer)
Dim Uhrzeit As Date
Uhrzeit = Now()
While Now() < DateAdd("s", AnzSekunden, Uhrzeit)
DoEvents
Wend
End Sub

Soweit sogut. Jedoch ergibt sich bei jedem Aufruf der "Warteschleife" eine 100%ige Prozessorauslastung für die Dauer des Schleifendurchlaufs, obwohl in der Funktion der Befehl "DoEvents" verwendet wird um eigentlich die Kontrolle dem Betriebssystem zurückzugeben. Gibt es irgend eine Möglickeit das Ganze irgendwie besser zu implementieren, sodass sich keine so hohe Prozessorauslastung mehr ergibt!????

Gruß
Schnarchzapfen

Arne Dieckmann
11.05.2004, 11:10
Versuche es einmal hiermit: http://www.mvps.org/access/api/api0021.htm

J_Eilers
11.05.2004, 11:22
@Arne Hast du eine Erklärung warum das so ist? Denn das DoEvents sollte ja eigentlich Ressourcen für das System freigeben, beanschlagt diese aber selber voll und ganz :confused:

Arne Dieckmann
11.05.2004, 11:42
@Jan: Nein, ich habe leider keine Ahnung. :(
Ich denke aber, dass Sascha :bye: eine Erklärung dafür hat (selbstverständlich darf auch jemand anderes sich dazu äussern).

J_Eilers
11.05.2004, 11:55
Hmmm *Vorsichtig eine Vermutung äußer*

Bei dem DoEvents durchläuft man in Access ja eine Schleife x-mal. Das bedarf schon alleine einer Rechenkapazität. Dann kommt noch das DoEvents hinzu, wobei ich keine Ahnung habe, was es eigentlich macht.
Hier hat Access 99% CPU-Auslastung, dafür ist das System aber noch ansprechbar.

Bei dem API wird die Zeit an die Kernel32 übergeben (Vermutung) und diese läßt das ganze System einschlafen (Leerlaufprozess 99%, alles andere 0%).

Eigentlich beides nicht so toll. Aber mit dem DoEvents kann man wenigstens noch andere Tasks ansprechen und diese öffnen sich. Zwar nicht so schnell, wie gewohnt, aber 50% CPU Auslastung bekommen die auch hin...

Mal sehen, ob hier jemand mehr Licht ins Dunkel bringen kann :idee: ;)

Sascha Trowitzsch
11.05.2004, 13:55
Der Ruf ward erhört...

Wie der Begriff DoEvents schon sagt geht es dabei um Ereignisse, die in Windows Messages heißen. Was der Befehl macht ist in der OLH etwas unglücklich ausgedrückt. Unter "Kontrolle an das BS übergeben" ist zu verstehen, dass die MessageQueue von Windows abgearbeitet werden soll. Das ist eine Warteschlange von Events für alle möglichen Meldungen, die an alle möglichen Fenster gehen. (Z.B. auch wm_paint, eine Meldung, die das Neuzeichnen von Fenstern anweist.) Und diese Warteschlange ermöglicht DoEvents dem BS abzuarbeiten. Es wird aber keine Änderung am ProcessScheduler veranlasst - es heißt ja auch nicht DoTasks. Deshalb bekommt der Leerlaufprozess keine höhere Priorität und die anderen Tasks auch nicht. Das Abarbeiten der MessageQueue indes verbraucht so wenig Rechenpower, dass die Auslastung für Access letztlich auf 100% bleibt - für deine Schleife.

HTH, Sascha

J_Eilers
11.05.2004, 14:04
@Sascha Ich denke ich habs, aber eine Frage nochmal zur Sicherheit. Angenommen ich hätte im Hintergrund einen Prozess, der viele Ressourcen verschlingt. Würde dieser dann im DoEvents gleichzeitig mit der Schleife abgearbeitet, anstatt das Access sonst die volle Leistung bekommen würde? Ist leider gar nicht meine Baustelle, aber ich würds gern wissen...dürfen :)

Mike
11.05.2004, 14:39
dann versucht doch mal diese Variante, die benötigt so gut wie keine CPU:

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub Warten(AnzSekunden As Integer)
Sleep AnzSekunden * 1000
End SubMike

Sascha Trowitzsch
11.05.2004, 15:28
@Jan:
Wieviel Rechenzeit ein Prozess unter Windows zugeteilt bekommt regelt der Task Scheduler. Standardmäßig ist normalen Applikationen eine durchschnittliche Zeitscheibe zugeteilt, d.h., dass alle in etwa gleich viel CPU verbrauchen - soweit die Theorie. Eine Anwendung kann aber leider mit API-Befehlen steuern, welche Priorität sie haben soll. Die Taskprioritäten sind in unterschiedliche Gruppen eingeteilt. Niedrig, normal, hoch und System. Treiber und diverse BS-Prozesse bekommen z.B. die höchste Priorität zugeteilt, weil es sich um zeitkritische Routinen handelt, die nicht unterbrochen werden dürfen. Aber man kann ohne weiteres mit API-Funktionen auch Access eine höhere Priorität einräumen, was wahrscheinlich aber nur dazu führt, dass man parallel kaum mehr sinnvoll mit anderen Anwendungen arbeiten kann, Access aber nicht nennenswert schneller wird. Umgekehrt kann Access auf niedrige Priorität gesetzt werden, was möglicherweise andere Prozesse beschleunigt.
Zur Frage mit der Schleife:
Access hat normale Priorität - also auch die Schleife. Wenn ein anderer Prozess ebenfalls normale Priorität hat und intensiv rechnet, dann müssten beide im Taskmanager 50% anzeigen. Übrigens kann man im Taskmanager ja die angezeigten Spalten selbst bestimmen und es gibt unter NT ff. auch den Punkt "Basispriorität", der dieses normal, hoch, etc. anzeigt. (Aber wie der Begriff schon sagt: Basispriorität ist quasi die Voreinstellung, die der Prozess wie beschrieben jederzeit ändern kann...)

HTH, Sascha

J_Eilers
11.05.2004, 15:31
Ok, ich denke dann hab ich es. Dankeschön für deine Geduld :hands: