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.
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.
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.
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.
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
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.