Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Probleme mit Genauigkeit von Thread.Sleep
christof.k
myCSharp.de - Member



Dabei seit:
Beiträge: 160

Themenstarter:

Probleme mit Genauigkeit von Thread.Sleep

beantworten | zitieren | melden

Hallo,

seit einigen Jahren schreibe ich an einer Applikation, um Nachrichten gesteuert auf dem CAN Bus zu senden (mittels Vector Hardware, wenn dies jemanden was sagt).
Dazu nutze ich folgendes Konstrukt

while(1)
{
   SendeNachricht();
   Thread.Sleep(5)
}
um alle 5ms die Funktion ablaufen zu lassen der dann entscheided, was zu senden ist.
Dies hat bisher immer blendend funktioniert (über Jahre hinweg).
Im laufe der Zeit muss sich aber "irgend etwas" geändert haben. Denn nun wird mein Thread im Normalfall immer nur alle 15 ms ausgeführt (auch wenn ich Thread.Sleep(1) probiere). Ich habe das nur durch Zufall herausbekommen und kann deshalb nicht sagen, was sich in der Umgebung (Windows) geändert hat. Win XP war immer das Betriebssystem.
Es kann nicht an der Rechnerpower liegen, da ich eine Updaterate von 0,3 ms bekomme, wenn ich das Thread.Sleep weglasse. Dies blockiert aber natürlich einen Kern.
Wir ist klar, dass Windows kein Echtzeitbetriebssystem ist, aber da es über eine lange Zeit hinweg wunderbar funktioniert hat bin ich so verwundert.
Hat jemand hierzu vielleicht einen Tip?

Vielen Dank im Voraus.
Christof
private Nachricht | Beiträge des Benutzers
t2t
myCSharp.de - Member



Dabei seit:
Beiträge: 436
Herkunft: Hamburg

beantworten | zitieren | melden

Schonmal versucht statt Thread.Sleep() einen Timer zu verwenden? Dieser blockiert dann natürlich das Programm auch nicht.
private Nachricht | Beiträge des Benutzers
talla
myCSharp.de - Experte

Avatar #avatar-3214.jpg


Dabei seit:
Beiträge: 7290
Herkunft: Esslingen

beantworten | zitieren | melden

Hallo,

ich kann mich t2t nur anschließen. Thread.Sleep als Timeralternative zu benutzen ist grober Unfug. Thread.Sleep wartet auch nur mindestens die spezifizierte Zeit. Es ist jederzeit möglich, dass Thread.Sleep erst später zurückkehrt. 5ms sind so oder so aber arg knapp. Allein durch das Thread Scheduling kanns zu viel längeren Wartezeiten kommen wenn es grad zu einem Threadwechsel kommt.
Baka wa shinanakya naoranai.

Mein XING Profil.
private Nachricht | Beiträge des Benutzers
Matthias Lauth
myCSharp.de - Member

Avatar #avatar-3344.gif


Dabei seit:
Beiträge: 50
Herkunft: DE

beantworten | zitieren | melden

Was passiert wenn Du die Priorität deines Prozesses erhöhst?

Zu den Timern gibt den tollen Artikel Comparing the Timer Classes in the .NET Framework Class Library, der u.A. die Präzision der Timer-Klassen behandelt.
private Nachricht | Beiträge des Benutzers
christof.k
myCSharp.de - Member



Dabei seit:
Beiträge: 160

Themenstarter:

beantworten | zitieren | melden

Hi,
Timer hatte ich sehr früh mal versucht, doch haben diese noch einen größeren Overhead, so dass dieses sehr schnell in eine Sackgasse geführt hat.....oder verstehe ich Dich falsch?

Danke
Christof
private Nachricht | Beiträge des Benutzers
ujr
myCSharp.de - Experte



Dabei seit:
Beiträge: 1770

beantworten | zitieren | melden

Hallo,

um die gewünschte Genauigkeit zu erreichen, kann man versuchen, mit einem Multimedia-Timer zu arbeiten. Dafür gibt's einen Wrapper bei Codeproject. Allerdings erreicht der die 5ms auch nur im Mittel.
Die 15ms sind übliche Dauer einer Zeitscheibe in Windows - das hat sich auch nicht kürzlich geändert. Verhält sich denn Dein Programm plötzlich anders?
private Nachricht | Beiträge des Benutzers
christof.k
myCSharp.de - Member



Dabei seit:
Beiträge: 160

Themenstarter:

beantworten | zitieren | melden

Hi,

ich habe für eine lange Zeit nur noch an den Nachrichteninhalten herumgeändert und deshalb nicht die Updaterate beobachtet.
Deshalb denke ich, dass es vor einem Jahr noch wunderbar funktioniert hat....schon schräg.
Es gibt Tools von der Firma, die die HW Herstellt. Diese schaffen diese hohe Auflösung ohne einen Prozuessorkern aufzubrauchen....

Vielleicht hat ja jemand noch eine Idee?

Danke
Christof
private Nachricht | Beiträge des Benutzers
t2t
myCSharp.de - Member



Dabei seit:
Beiträge: 436
Herkunft: Hamburg

beantworten | zitieren | melden

Zitat von christof.k
Es gibt Tools von der Firma, die die HW Herstellt. Diese schaffen diese hohe Auflösung ohne einen Prozuessorkern aufzubrauchen....

Die werden mit großer Wahrscheinlichkeit kein Sleep() verwenden. Da dieses, wie du schon selbst sagtest, einen ganzen Kern "lahm legt". Genau das umgehst du auch, wenn du einen Timer einsetzt. Ich weiß ja nicht, wie du deine Architektur aufgezogen hast, aber sollte es dir einigermaßen leicht möglich sein, dann empfehle ich dir zumindest mal testweise die Timer-Variante einzubauen und zu schauen, wie es sich dann verhält.

Moderationshinweis von herbivore (19.03.2012 - 17:41:08):

Thread.Sleep legt nichts lahm, außer dem Thread, der das Thread.Sleep aufruft. Thread.Sleep gibt den zuvor belegten Kern für andere Threads frei. Ein Thread der schläft verbraucht keine Rechenzeit.

private Nachricht | Beiträge des Benutzers
christof.k
myCSharp.de - Member



Dabei seit:
Beiträge: 160

Themenstarter:

beantworten | zitieren | melden

Hallo,

habe gerade den Aufruf der Funktion durch einen Timer gesteuert und egal ob ich den "normalen" oder den Multimedia-Timer nutze, die schnellste Updaterate ist 15 ms.
Nur wenn ich eine Stopwatch in den Thread einbaue, die für genau 5 ms den Thread blockiert, bekomme ich das gewünschte Ergebniss.

Ich frage mich, wie dass andere kommerzielle Tools lösen, die eine hohe zeitl. Auflösung realisieren.

Bis bald
Christof
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo christof.k,

wie andere Programme das machen, weiß ich nicht.

Wenn es bei dir vorher mit Thread.Sleep geklappt hat, war das wohl pures Glück. Die Ungenauigkeiten von Thread.Sleep (und leider auch von den meisten Timer-Typen) sind bekannt und wurden im Forum schon öfter thematisiert. Selbst mit 15ms Intervall, also 10ms Abweichung, hast du - bezogen auf Thread.Sleep (und die meisten Timer) - sogar immer noch ziemliches Glück.

herbivore
private Nachricht | Beiträge des Benutzers
Matthias Lauth
myCSharp.de - Member

Avatar #avatar-3344.gif


Dabei seit:
Beiträge: 50
Herkunft: DE

beantworten | zitieren | melden

Könnte er sich einen Vorteil verschaffen, wenn er zum senden der Nachricht an den CAN Bus den Latenzmodus des Garbage Collectors auf LowLatency setzt?
private Nachricht | Beiträge des Benutzers
ujr
myCSharp.de - Experte



Dabei seit:
Beiträge: 1770

beantworten | zitieren | melden

Hallo,

der Multimedia-Timer hat prinzipiell eine Genauigkeit von 1ms. Wenn es bei Dir 15ms sind, hast Du was falsch gemacht.

Zitat von Matthias Lauth
den Latenzmodus des Garbage Collectors auf LowLatency setzt?

Kaum, da das Problem nichts mit dem GC zu tun hat, sondern systembedingt ist.
private Nachricht | Beiträge des Benutzers
talla
myCSharp.de - Experte

Avatar #avatar-3214.jpg


Dabei seit:
Beiträge: 7290
Herkunft: Esslingen

beantworten | zitieren | melden

Hallo,

ist es denn überhaupt nötig einen Timer zum Senden auf PC Seite zu haben? Die Hardware hat doch eh eigene Sende- und Empfangspuffer. Kann man dort die zu versendenen Nachrichten nicht blockweise reinschieben und die HW sendet das mit dem eigenen Timer nach dem angegebenen Sendeintervallbei zyklischen Nachrichten? Grad bei den per USB angeschlossenen Boxen könnte man es doch sonst vergessen mit einigermaßen genauer Kommunikation, da ja auch USB lange nicht die Genauigkeit bietet die notwendig ist bei den verschiedenen Bussystemen.
Baka wa shinanakya naoranai.

Mein XING Profil.
private Nachricht | Beiträge des Benutzers
NoLimit
myCSharp.de - Member



Dabei seit:
Beiträge: 194
Herkunft: Simmozheim (nähe Stuttgart)

beantworten | zitieren | melden

Also ich habe einen Prüfstand entwickelt, der auch per CAN-Bus am PC hängt.
Ich verwende dazu den IXXAT Adapter.
Vielleicht kann ich dir ja weiterhelfen, wenn ich mal dein Problem richtig kenne
"If you give someone a
program, you will frustrate them
for a day; if you teach them how to
program, you will frustrate them
for a lifetime." :evil:
private Nachricht | Beiträge des Benutzers