Autor Beitrag
Xzeer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 62



BeitragVerfasst: Mo 08.11.10 17:55 
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???

_________________
Xzeer
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 62



BeitragVerfasst: 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.

_________________
Xzeer
gfoidl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 157
Erhaltene Danke: 19

Win XP
C#, Fortran 95 - Visual Studio
BeitragVerfasst: 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ü

_________________
Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 09.11.10 17:06 
user profile icongfoidl hat folgendes geschrieben Zum zitierten Posting springen:
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, user profile iconXzeer.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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 geht nicht.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 09.11.10 20:04 
Hallo Ralf,

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

Interessant ist besonders diese Anwendung: www.lucashale.com/timerresolution/ -)
Xzeer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 62



BeitragVerfasst: 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.

_________________
Xzeer
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 62



BeitragVerfasst: 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?

_________________
Xzeer
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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. :(


Zuletzt bearbeitet von Ralf Jansen am Di 09.11.10 22:13, insgesamt 1-mal bearbeitet
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 09.11.10 22:09 
user profile iconXzeer hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 62



BeitragVerfasst: 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:

_________________
Xzeer
ujr
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 102
Erhaltene Danke: 12



BeitragVerfasst: Fr 17.12.10 01:02 
user profile iconXzeer hat folgendes geschrieben Zum zitierten Posting springen:
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:
www.codeproject.com/...multimediatimer.aspx
Threads wären evtl. mit "Waitable"-Timern eine Möglichkeit: www.codeproject.com/...bletimerwrapper.aspx