Entwickler-Ecke
Basistechnologien - Welchen Timer denn nun?
Xzeer - Mo 08.11.10 17:55
Titel: Welchen Timer denn nun?
Hi,
Ich habe gerade die Übersicht über verfügbare Timer verloren.
Was ich suche ist ein möglichst genauer, vor allem aber schneller Timer, der im Grunde als einzige Funktion regelmäßig eine Methode aufrufen muss.
Welcher eignet sich dazu am besten?
-> Windows.Forms.Timer
-> Timers.Timer
-> Threading.Timer
Oder lieber doch versuchen einen selbst zu basteln???
Ralf Jansen - Mo 08.11.10 19:25
Was meinst du genau mit schnell? Wenn du meinst das der Timer Code möglichst zeitnah zur Auslösung des Timers laufen soll dann am ehesten der Threading.Timer.
Wenn du wirklich eine ganz genaue Auflösung für echtzeitähnliche Anwendungen brauchst dann solltest du die die QueryPerformanceCounter API von Windows ansehen.
Xzeer - Mo 08.11.10 20:39
Na also Echtzeit muss es nicht sein.
Mit schnell meine ich, dass Wiederholungen im 10ms Sekunden Bereich ohne Probleme möglich sein sollten.
gfoidl - Di 09.11.10 12:14
Hallo,
selber basteln ist wohl die schlechteste Variante. Die anderen 3 Timer von .net* sind ausgereift und getestet.
* eigentlich 4 denn WPF hat noch den DispatcherTimer als Pendant zum Winforms-Timer.
Winforms-Timer hat den Vorteil dass der Ereignishandler im UI-Thread ausgeführt wird, d.h. es ist kein Control.Invoke wie bei den anderen beiden notwendig. Hier muss aber die Arbeit im Tick schnell genug ausgeführt werden sonst kann das 10ms Intervall nicht gehalten werden.
Der Timers.Timer ist für Server-Szenarien vorgesehen und der Threading.Timer (den ich nehmen würde) ist das "universellste".
mfG Gü
Th69 - Di 09.11.10 12:52
Der Window-Timer hat aber nur eine Auflösung von ca. 14-15ms -)
Bei den anderen Timern weiß ich es nicht genau, bin mir aber trotzdem ziemlich sicher, daß diese auch nicht exakt 10ms einhalten können.
Yogu - Di 09.11.10 17:06
gfoidl hat folgendes geschrieben : |
| selber basteln ist wohl die schlechteste Variante. |
Das kommt ganz auf das Problem an. Nicht für jede Situation wurde bereits die perfekte Komponente entwickelt.
Wenn es wirklich auf
sehr genaue Zeiten ankommt, und die CPU-Auslastung zweitrangig ist, hätte ich noch eine andere Idee: In einer Schleife ständig
QueryPerformanceCounter aufrufen und zur richtigen Zeit die Schleife verlassen. Das ist dann zwar kein normaler Timer mehr, aber dafür kann der, wenn die CPU nicht allzu stark belastet ist, auf Millisekunden oder vielleicht noch genauer auslösen.
Möglicherweise ist es auch gar nicht notwendig, genau alle 10 Sekunden etwas durchzuführen? Mit
QueryPerformanceCounter kannst du herausfinden, wie viel Zeit seit dem letzten Tick vergangen ist, und die Vorgänge entsprechend anpassen. Wenn beispielsweise ein physikalisches System in Echtzeit simuliert werden soll, ist es wichtig, ganz genau zu wissen, wie viel Zeit vergangen ist; eher nebensächlich ist es, ob wirklich immer im exakten Intervall ein Rechendurchlauf durchgeführt wird.
Kurz: Wir bräuchten mehr Informationen,
Xzeer.
Ralf Jansen - Di 09.11.10 19:22
| Zitat: |
| Winforms-Timer hat den Vorteil dass der Ereignishandler im UI-Thread ausgeführt wird, d.h. es ist kein Control.Invoke wie bei den anderen beiden notwendig. Hier muss aber die Arbeit im Tick schnell genug ausgeführt werden sonst kann das 10ms Intervall nicht gehalten werden. |
Keine Chance. Der Winforms Timer hängt an der klassischen Timer API. Genauer als
55ms [
http://blogs.msdn.com/b/oldnewthing/archive/2004/12/02/273721.aspx] geht nicht.
Xzeer - Di 09.11.10 21:18
Okay, wie gewünscht mehr Infos:
Ich programmiere an einem Programm, das eine selbst entwickelte Anlage (Hochreagllagerroboter) steuern soll.
Dazu brauche ich einen Timer, der die Sensoren einließt und das Motorboard schaltet. Dieser Timer muss also möglichst schnell arbeiten, damit die Reaktionszeit der Anlage nicht zu langsam ist.
Yogu - Di 09.11.10 21:24
Ah, das hört sich doch schon mal gut an. Bist du dir sicher, dass du einen Timer brauchst? Ich hätte nämlich einen anderen Vorschlag: Starte einen neuen Thread mit einer Endlosschleife. In dieser Schleife überwachst du die Sensoren und steuerst die Anlage. Wenn das die CPU-Last zu hoch treibt, kannst du ja nach jeden Durchgang für ein paar Millisekunden Thread.Sleep aufrufen. Einen Timer würde ich nur verwenden, wenn Formulare geändert werden müssen oder ein bestimmtes Intervall eingehalten werden muss. Beides scheint bei dir nicht der Fall zu sein.
Xzeer - Di 09.11.10 21:41
jaein indirekt natürlich schon, da manche Sensorwerte auch im Formular angezeigt werden.
Wenn ich also jetzt auf einen Thread zurückgreife bekomme ich doch bestimmt Probleme mit Threadsicheren/Threadübergreifenden Zugriffen, oder nicht?
Ralf Jansen - Di 09.11.10 21:48
| Zitat: |
| die "Timer Resolution" bei moderneren Windows-Systemen (d.h. NT, XP, Vista, 7) hat aber meine erwähnten ca. 14-15ms, s.a. msdn.microsoft.com/e...gazine/cc163996.aspx |
Die Msdn Hilfe zum Windows.Forms.Timer(nur auf den bezog mich meine Aussage) spricht ebenfalls von 55ms. Ist aber wahrscheinlich dann ein Dokumentationsfehler. Bei einem kurzen Check (was geht schon über einfach mal ausprobieren anstatt Theorie) kommen eher Werte um die besagten 15ms raus.
Edit: Die beiden anderen treffen genau die 15ms. Drunter kann scheinbar keiner der 3 Timer. :(
Yogu - Di 09.11.10 22:09
Xzeer hat folgendes geschrieben : |
jaein indirekt natürlich schon, da manche Sensorwerte auch im Formular angezeigt werden.
Wenn ich also jetzt auf einen Thread zurückgreife bekomme ich doch bestimmt Probleme mit Threadsicheren/Threadübergreifenden Zugriffen, oder nicht? |
Wenn du Sensorwerte im Formular anzeigen willst, sollte das sowieso getrennt von der Steuerung durchgeführt werden. Wenn die Steuerung aus irgendeinem Grund mal hängt, wäre es doof, wenn das Formular deswegen auch nicht reagieren würde. Also solltest du einen
System.Windows.Forms.Timer mit einem Intervall von ca. 100ms oder so erstellen und dort auf die Eigenschaften der Steuerklasse zugreifen (wenn die Werte zu schnell aktualisiert werden, sieht man unter Umständen gar nichts mehr). Alternativ wäre es auch möglich, Eigenschaften, die ausgelöst werden, wenn sich ein Wert ändert, zur Steuerklasse hinzuzufügen, die das Formular dann abonnieren kann.
Xzeer - Fr 12.11.10 17:49
So bin in der Zwischenzeit tatsächlich komplett auf Threads umgestiegen und es klappt alles so wie ich es mir wünsche. :dance2:
ujr - Fr 17.12.10 01:02
Xzeer hat folgendes geschrieben : |
| So bin in der Zwischenzeit tatsächlich komplett auf Threads umgestiegen und es klappt alles so wie ich es mir wünsche |
Auch wenn die Anfrage etwas her ist - die Genauigkeit der Timer kann man mit ja mit der StopWatch-Klasse prüfen. Da sieht man dann, dass alle genannten Timer unter bzw. um 100ms deutliche Abweichungen vom Soll aufweisen.
Wesentlich genauer ist der Multimediatimer. Für den gibt's auf Codeproject auch schon eine Wrapper-Klasse:
http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx
Threads wären evtl. mit "Waitable"-Timern eine Möglichkeit:
http://www.codeproject.com/KB/miscctrl/waitabletimerwrapper.aspx
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!