Guten Morgen, für eine GUI Anwendung benutze ich einen WIndows.Forms.Timer der zyklisch mi 1 Sekunde läuft. Innerhalb dieses Timers verwende ich noch die Funktion Thread.Sleep(...). Das mit dem Thread.Sleep gefällt mir nicht. Wie könnte man eine Verzögerung innerhalb einer WIndows.Forms.Timers realisieren? Das TimerEvent synchronisiere mit der GUI Applikation anhand der Invoke Methode.
Warum nimmst du nicht gleich einen zweiten Thread? Das wäre glaubich einfacher... Etwa so:
1 | mMustWork = true; |
2 | var thread = new Thread(MyThread); |
3 | thread.Start(); |
4 | |
5 | |
6 | private void MyThread() |
7 | {
|
8 | while(mMustWork) |
9 | {
|
10 | Thread.Sleep(1000); |
11 | DoStuff(); |
12 | Thread.Sleep(20); |
13 | DoMoreStuff(); |
14 | }
|
15 | }
|
:
Bearbeitet durch User
Könnten da Probleme im laufenden Betrieb entstehen, wenn Thread.Sleep im System.Windows.Forms.Timer verwendet wird?
Moin, da der timer_tick im Thread der GUI läuft, tauchen bei Wartezeiten auch die üblichen Probleme auf.
Leonhard schrieb: > Das TimerEvent synchronisiere mit der GUI Applikation anhand der Invoke > Methode. Das solltest du nicht machen, weil nicht"Gast" schrieb: > der timer_tick im Thread der GUI läuft Bitte beschreibe doch mal das komplette Problem - einschließlich des Zwecks der Verzögerung - auf einer allgemeinen Ebene (ganz unabhängig von möglichen spezifischen Implementierungen, die du bereits ins Auge gefasst hast).
Innerhalb des Timers (zyklisch 1 Sekunde) sollen im Abstand von 20ms Nachrichten gesendet werden. Beispiel mit 3 Nachrichten: Timer startet zyklisch mit 1 Sekunde --> zyklische Timer --> Nachricht 1 senden --> 20 ms warten --> Nachricht 2 senden --> 20ms warten --> Nachricht 3 senden --> 20ms warten
Ich habe im letzten Beitrag noch was vergessen. Beispiel mit 3 Nachrichten: --> Timer startet zyklisch mit 1 Sekunde --> zyklische Timer --> Nachricht 1 senden --> 20 ms warten --> Nachricht 2 senden --> 20ms warten --> Nachricht 3 senden --> 20ms warten --> Callback --> Nachricht erfolgreich gesendet, Daten in GUI visualisieren --> Timeout, Daten in GUI visualisieren
Ich würde auch nen Thread nehmen. Man könnte aber auch z.B. einen 20ms-Timer nehmen und was im Timer jeweils geschehen soll ("Nachricht 1", "Nachricht 2", ...) via Statemachine lösen.
Was gefällt dir denn an meiner Lösung mit dem Thread nicht? ;-) Damit sollte das doch ganz einfach sein...
Ich hab da mal schnell was zusammengehäckt, wie ich das machen würde. Kommentiert habe ich absichtlich nicht. Da lernt man ja sonst nichts dabei :)
1 | using System; |
2 | using System.Collections.Generic; |
3 | using System.Linq; |
4 | using System.Text; |
5 | using System.Threading; |
6 | using System.Threading.Tasks; |
7 | using System.Timers; |
8 | |
9 | namespace ConsoleApplication5 { |
10 | class Program { |
11 | static void Main(string[] args) { |
12 | SendMessages mh = new SendMessages(new List<string>() { "hallo", "welt", "das", "geht","gut"}, 1000); |
13 | |
14 | while (true) |
15 | Thread.Sleep(1); |
16 | } |
17 | } |
18 | |
19 | class SendMessages { |
20 | private List<string> messages; |
21 | private List<string>.Enumerator messageIterator; |
22 | private System.Timers.Timer sendTimer; |
23 | |
24 | |
25 | public SendMessages(List<string> messagesToSend, int sendEveryMillisecound) { |
26 | sendTimer = new System.Timers.Timer(); |
27 | sendTimer.Interval = sendEveryMillisecound; |
28 | sendTimer.Elapsed += doSendMessage; |
29 | |
30 | messages = new List<string>(messagesToSend); |
31 | messageIterator = messages.GetEnumerator(); |
32 | |
33 | sendTimer.Start(); |
34 | } |
35 | |
36 | void doSendMessage(object sender, ElapsedEventArgs e) { |
37 | if (messageIterator.MoveNext()) { |
38 | Console.WriteLine(messageIterator.Current); |
39 | } |
40 | else { |
41 | Console.WriteLine("Alle Nachrichten gesendet"); |
42 | sendTimer.Stop(); |
43 | } |
44 | } |
45 | } |
46 | } |
hm, wenn ich mir das so anschau.... Das ist aus dem Handgelenk geschossen. Mir fallen da noch ein paar Sachen auf. Das soll ja aber auch nur das Prinzip darstellen.
Guten Morgen erstmal vielen Dank für die Hilfe. In der GUI Anwendung habe ich sämtliche Elemente die ich mit Daten befüllen muss. Diese Daten würden dann im Thread verarbeitet werden. Nun wie kann ich die Daten von dem Thread auf der GUI ausgeben, ohne das ein Excaption auftritt?
Leonhard schrieb: > Nun wie kann ich die Daten von dem > Thread auf der GUI ausgeben, ohne das ein Excaption auftritt? Das Problem hast du doch bereits gelöst ;-) Leonhard schrieb: > Das TimerEvent synchronisiere mit der GUI Applikation anhand der Invoke > Methode.
:
Bearbeitet durch User
Ich meine nicht den Thread für die GUI sondern einen separaten Thread.Timer der zyklisch läuft.
Vorher (nur mit dem Forms-Timer; es gibt auch andere), war Invoke/BeginInvoke unnötig, da sich dieser Timer im GUI-Thread zurückmeldet. Aber in deinem Extra-Thread musst du es nun verwenden, um auf die GUI zugreifen zu können.
BTW: Ich hoffe, dass genaues Timing (sagen wir mal, +/-30ms) nicht notwendig ist bei deinem Programm, denn sonst wär die Verwendung des Form-Timers und Sleep problematisch. Wobei Windows natürlich ohnehin kein Echtzeit-Betriebssystem ist.
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.