Forum: PC-Programmierung VB6 API-Funktion "Sleep"


von Klaus D. (rodo38)


Angehängte Dateien:

Lesenswert?

Geehrtes Forum,

Probleme mit der API-Funktion "Sleep"

Basis Infos:

Windows XP SP3
Visual Basic 6.0 Prof.
Rechner 1: 1 Core,  2.8 GHz, Multithreading
Rechner 2: 2 Cores, 3.2 GHz, Multithreading

wegen der bekannten Probleme mit dem Timer (Auflösung ca. 50 ms, obwohl 
man 1 ms eingeben kann), benutze ich seit Jahren die API-Funktion 
"Sleep", um z.B. Wartezeiten zu erzeugen.

Zuletzt wollte ich eine Sinus Kurve, welche aus 512 Y-Werten besteht, 
die mittels For Next in die 512 Spalten in einem Image gezeichnet 
werden, mittels eines "Sleep 1" in jeder Schleife so gestalten, dass sie 
nicht plötzlich erscheint, sondern dass sie langsam gezeichnet wird.

Das hat auch zunächst funktioniert. Bei "Sleep 1" dauerte das Zeichnen 
der Kurve etwas mehr als 0,5 Sekunden, bei "Sleep 2" etwas mehr als 1 
Sekunde usw., wie erwartet.

Irgendwann dauerte der Vorgang auf einmal ca. 16 Sekunden, egal welchen 
Wert ich eingab: "Sleep 1" bis "Sleep 15". Natürlich dachte ich sofort 
an einen Programmierfehler meinerseits. Deshalb habe ich das hier 
angehängte Programm "SleepTimeCheck" geschrieben. Doppelklick auf 
"SleeTimeCheck.exe" öffnet das Programm. Eine installiertes Visual Basic 
ist dafür nicht erforderlich.

Mit Hilfe der Bilder hoffe ich, das Problem verständlich machen zu 
können. Ins Programm eingeben kann man Werte für die Sleep-Zeit sowie 
für die Anzahl der Schleifen. Das jeweilige Resultat wird im Fenster zu
"[ms] Zeit Pro Schleife" angezeigt.
Mittels der Option Buttons kann man das Verhalten des Programms 
beeinflussen. Egal, welche Kombination man wählt, die Resultate sind 
immer dieselben.

Bild 01: Die Programm-Oberfläche
Bild 02: Eine Liste der Resultate bei verschiedenen Eingaben ins
         Fenster "Sleep-Zeit"
Bild 03: Das Verhalten des Programms, wenn gleichzeitig ein Video 
mittels
         des Programms "DVBViewer" läuft
Bild 04: Das Verhalten des Programms, wenn gleichzeitig mehrere 
Instanzen
         davon laufen
Bild 05: Die Resultate, wenn alle Instanzen fertig sind
Bild 06: Die Resultate, wenn mein E-Mail Programm (in Firefox) läuft.
         Damit sich das so verhält, muß ich eingeloggt sein

Zu Bild 03:
Es ist egal, welches Abspiel-Programm für Videos benutzt wird. Falls der 
DVBViewer ein TV-Programm anzeigt, verhält sich "SleepTimeCheck" genau 
so, wie beim Abspielen eines Videos (*.mpg)

Zu Bild 03 und Bild 06:
Bisher ist mir, ausser den Video-Abspielprogrammen, nur das 
E-Mail-Programm bekannt, welche den Effekt hervorrufen, dass bei "Sleep 
1" nicht 15,625  ms sondern ca. 2 ms herauskommen.

Bisherige Massnahmen:

1.
Statt Rechner 1 wurde der Rechner 2 benutzt. Keine Änderung.
2.
Ausbau der Festplatte mit der Partition C:\ aus Rechner 1, Einbau in den 
Rechner 2. Partition C:\ formatiert und mittels "EASEUS Partition 
Master", Funktion "Wipe" 1 Mal überschrieben.
3.
Festplatte zurück in den Rechner 1, Windows neu installiert. Hierbei 
kein Anschluss ans Internet (RJ45 Stecker gezogen). Virenbefall deshalb 
eher unwahrscheinlich. Ausser "SleepTimeCheck" wurde auch nichts anderes 
installiert.
4.
Statt API "Sleep" die APIs "SleepEx" und "TimeGetTime" benutzt. Keine 
Änderung.

Noch eine Bemerkung:
Wenn der Quellcode nicht geöffnet werden kann, weil kein Visual Basic 
installiert ist: Die Dateien mit den Endungen ".frm", ".bas", ".vbp" und 
".vbw" kann man mit einem Editor öffnen. Hier wird der Quellcode in gut 
verständlichem Klartext angezeigt.

Mir fällt nichts mehr ein, was ich noch tun könnte. Kann mir jemand 
helfen?

Mit herzlichem Dank für die Mühe

Klaus D.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die Granularität der Windows-Timerfunktionen liegt normalerweise bei 10 
msec*, kann aber durch Aufruf der Win32-API-Funktion timeBeginPeriod 
bis auf 1msec herunter reduziert werden. Diese Einstellung ist 
systemweit aktiv.

http://msdn.microsoft.com/de-de/library/windows/desktop/dd757624%28v=vs.85%29.aspx

Multimediaprogramme wie Videoabspielprogramme nutzen diese Funktion, sie 
wird von MS auch den Multimediafunktionen zugerechnet.


*) zu Zeiten des 16-Bit-Steinzeit-Windows waren das 50 msec, der Wert 
wurde mit den ernstgemeinten Windows-Versionen zunächst auf 15, und dann 
später auf 10 msec reduziert.

von Peter II (Gast)


Lesenswert?

Ich habe mir den Quelltext nicht angeschaut aber mal eine Idee:

Nich immer 1ms(oder so) warten und denn den nächsten punkt zeichnen, 
sondert rechnen zu welcher zeit man wie viele Punkte malen könnte. Damit 
Hast du auf jeden Fall eine Konstante laufzeit.

von Klaus D. (rodo38)


Lesenswert?

Hallo rufus,

das ging ja blitzschnell und mit durchschlagendem Erfolg. Ich möchte 
Ihnen wirklich ganz herzlich danken. Das selbstständig zu finden, 
scheint nahezu unmöglich zu sein. Der "API-Guide" ist meines Wissens die 
beste Quelle für diese Funktionen. Da steht es nicht drin. Wie sind Sie 
an dieses Wissen gelangt? Ich frage das, um evtl. selbst etwas 
Grundsätzliches dazuzulernen.

Damit auch andere was davon haben, hier die Code-Ausschnitte:

    Public Declare Function timeBeginPeriod Lib "winmm.dll" _
    (ByVal uPeriod As Long) As Long

    Public Declare Function timeEndPeriod Lib "winmm.dll" _
    (ByVal uPeriod As Long) As Long

    timeBeginPeriod 1
    For I = 1 To J
        If G = 1 Then Exit For
        Sleep Val(txtTime.Text)
        txtI.Text = I
        If optRefresh.Value = True Then txtI.Refresh
        If optDoEvents.Value = True Then DoEvents
        If optScrollOn.Value = True Then HScroll.Value = I
    Next I
    timeEndPeriod 1

------------------------------------------------------------------------

Hallo Peter II,

auch Ihnen meinen herzlichen Dank. Es ging mir aber nicht darum, wie man 
das Problem umgehen oder anders lösen kann. Ich habe mich, damit ich in 
meinem Projekt erstmal weiterkam, mit einer For Next Schleife statt des 
Sleep - Aufrufs beholfen.
Weil solche For Next Schleifen auf verschiedenen Computern verschieden 
schnell ablaufen, lässt sich meine noch mittels eines Faktors von 0.01 
bis 9999 "justieren".
Interessant wird sein, ob die Geschwindigkeit dieser For Next Schleife 
durch "timeBeginPeriod" beeinflusst wird und wenn ja, wie. Dazu habe ich 
aber heute Abend keine Lust mehr.

Nochmals ein wirklich ernstgemeintes Dankeschön an Sie beide

Beste Grüße

Klaus D.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Klaus D. schrieb:
> Der "API-Guide" ist meines Wissens die
> beste Quelle für diese Funktionen. Da steht es nicht drin. Wie sind Sie
> an dieses Wissen gelangt?

Ich weiß nicht, was der "API-Guide" sein soll; die 
Betriebssystemfunktionen sind in der MSDN-Dokumentation beschrieben, die 
derzeit unter dem von mir angegebenen Link zu finden ist.

Entgegen der Beschreibung in diesem Link gibt es diese Funktion schon 
deutlich länger, sie war bereits in NT3.1 enthalten*, und mit dem habe 
ich mich vor 20 Jahren beschäftigt. Damals gab es allerdings noch keine 
im Internet verfügbare Dokumentation der Win32-API, sondern nur die 
"MSDN-CD", auf der man mit einer alle paar Jahre durch ein anderes 
ersetztes mehr oder weniger unbedienbaren Programm suchen durfte ...

*) das gibt MS hier auch zu:
http://technet.microsoft.com/en-us/subscriptions/ms713413%28v=vs.85%29.aspx

von API-Guide (Gast)


Angehängte Dateien:

Lesenswert?

Hallo rufus,

Sie schrieben:

> Ich weiß nicht, was der "API-Guide" sein soll

im Anhang kommen ein Bild der Oberfläche sowie die Setup Datei des
API-Guide 3.7

Mit Ihrem Link werde ich mich beschäftigen. Vielen Dank.

Beste Grüße

Klaus D.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

API-Guide schrieb:
> im Anhang kommen ein Bild der Oberfläche sowie die Setup Datei des
> API-Guide 3.7

Danke, aber ich brauche so etwas nicht, da ich nicht mit VB6 (oder einer 
anderen Version davon) arbeite, und die offizielle Dokumentation der 
Win32-API auch schon seit längerem kenne, wie ich ja auch schon 
schilderte.

Nun ist es so, daß manche Leute zu begrifflichen Unschärfen neigen, und 
es hätte mich nicht überrascht, wenn jemand die MSDN-Dokumentation der 
Win32-API auch als "API-Guide" bezeichnet hätte.

Das Tool ist aber sicherlich für VB-Anwender wertvoll.

PS:
Screenshots bitte nicht als PDF.

von Jojo S. (Gast)


Lesenswert?

Die Zeitscheibendauer ist meines Wissens nach auch vom Betriebssystem 
abhängig (Desktop oder Server Variante) und von der CPU (1 oder mehr 
Kerne).  Das ist bei Windows leider sehr undurchsichtig, Abhilfe schafft 
eigentlich nur den Multimediatimer zu benutzen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.