Laden...

Hintergrund-Timer immer aktiv und überall verfügbar machen

Erstellt von Meson vor 7 Jahren Letzter Beitrag vor 7 Jahren 2.049 Views
M
Meson Themenstarter:in
4 Beiträge seit 2017
vor 7 Jahren
Hintergrund-Timer immer aktiv und überall verfügbar machen

Hallo Leute,

habe gerade erst mit C# angefangen, und hoffe mir kann hier jemand weiterhelfen.
Bisher programmiere ich fast nur Microcontroller in C, deshalb bitte ich um etwas Nachsicht bei meiner Terminologie und meinen Ansätzen 😉.
Habe mit der Suchfunktion leider nichts gefunden, da ich nicht mal genau weiß, wonach ich C#-spezifisch suchen sollte (...wäre vielleicht schon ein Teil der Antwort 😉)

Mein Problem ist folgendes: Ich bräuchte einen Timer, der im Programm IMMER läuft, und auf den ich von allen Methoden aus abfragen kann.
Z.B. wenn ich auf eine bestimmte Anzahl von Daten im Receive-Buffer des Com-Ports warte, soll die Warteschleife nach 500ms abgebrochen werden.
Bei meinem Test-Beispiel unten friert natürlich das GUI ein und nicht einmal der Label-Text vor der Schleife ("DoWhile START") wird ausgegben (?).
Gibt es da vielleicht eine einfache Möglichkeit, das Problem zu lösen, bzw. einen Ansatz, den ich auch als Anfänger halbwegs verstehen kann?

Vielen Dank!!
Meson


System.Timers.Timer theTimer;
public static uint TimerCount = 0;

private void cmdStart_Click(object sender, EventArgs e)
{
	theTimer = new System.Timers.Timer(100);
	theTimer.Elapsed += PollUpdates;
	theTimer.Start();
}

private void PollUpdates(object sender, EventArgs e)
{
	// alle 100ms wird der Timer ausgelöst und zählt eins hoch
	TimerCount++;
	lblCounter.Text = Convert.ToString(TimerCount);  // Timerfortschrit im 1. Label anzeigen
}


private void cmdTest2_Click(object sender, EventArgs e)
{
    lblDoWhile.Text = ("DoWhile START");  // Text im 2. Label anzeigen

	do
	{
		// Warte auf irgenwas, z.B. das der Receivebuffer vom COM-Port eine bestimmte Anzahl Zeichen hat
		// Timer soll trotz dieser Schleife im 1. Label weiter hochgezählt werden, d.h. PollUpdates soll weiterhin alle 100ms ausgeführt werden

	} while (TimerCount < 2000);

	lblDoWhile.Text = ("DoWhile STOP");  // Text im 2. Label anzeigen
}
16.806 Beiträge seit 2008
vor 7 Jahren

[FAQ] Warum blockiert mein GUI?

Ein Timer, der von überall verfügbar ist, ist ein Fehldesign.
Wenn Du genauer beschreibst, warum Du denkst, dass Du das brauchst - und was Du damit erreichen willst - kann man Alternativen anbieten.

Gewöhn Dir auch gar nicht erst an, Programmlogik in die UI zu packen.
Das machst Dir ansonsten später nur schwerer, geschweige denn, dass Du oft Deinen eigenen Code nicht (mehr) nachvollziehen kannst bzw. die Übersicht verlierst..
[Artikel] Drei-Schichten-Architektur

U
1.688 Beiträge seit 2007
vor 7 Jahren

Z.B. wenn ich auf eine bestimmte Anzahl von Daten im Receive-Buffer des Com-Ports warte, soll die Warteschleife nach 500ms abgebrochen werden.

Dafür gibt es bspw. die Eigenschaft "ReadTimeout" der SerialPort-Klasse.

Etwas wie "Warteschleifen" solltest Du auch nicht verwenden. Im Unterschied zur Mikrocontroller-Programmierung gehört der Prozessor nicht nur einer Anwendung oder einem Vorgang (Thread). Stattdessen erfolgt die Entwicklung eher "ereignisgesteuert" (wenn eine Aktion durch die GUI ausgelöst wird, wenn ein IO-Vorgang beendet ist [erfolgreich oder fehlgeschlagen]).

M
Meson Themenstarter:in
4 Beiträge seit 2017
vor 7 Jahren

Vielen Dank für die schnellen Antworten!

Werde versuchen die Programmlogik separat zu halten.

...aber vielleicht gibt es zu meinem konkreten Problem doch noch einen Tip oder einen C# Denkansatz die ich nachvollziehen kann (...würde ja schon gerne was dazulernen):

Vorneweg: ich versuche nur ein kleines Tool zu schreiben mit dessen Hilfe ich mit einem Microcontroller kommunizieren kann, um z.B. einen Status abzufragen oder Befehle zu senden. Nicht aufregendes, sondern wie gesagt eher ein Tool.

Ich schicke deshalb über den Com-Port eine Anfrage aus z.B. 7 Zeichen an den Mikrocontoller (was mir bereits gelungen ist 😉) und erwarte eine Anwort mit einer bestimmten Anzahl (z.B. 10) an Zeichen innerhalb einer Zeit von 500ms. Wenn innerhalb dieser Zeit nicht die richtige Anzahl angekommen ist, wird die Anfrage nochmal gesendet bzw. eine Fehlermeldung ausgegeben.

Nach meinem Verständnis müßte ich doch jetzt den ReceiveBuffer des Com-Ports 500ms lang überwachen und gucken, ob da was kommt. Und wenn die richtige Anzahl an Zeichen im Buffer ist, diesen dann auslesen und weiterverarbeiten.

...aber wahrscheinlich ist das in C# ganz anders.

Wäre dankbar, wenn mir hier jemand weiterhelfen könnte.

Grüße,
Meson

U
1.688 Beiträge seit 2007
vor 7 Jahren

s. z.B. hier Template SerialPort

Aber auch die Doku :rtfm: zu SerialPort ist hilfreich.

Schließlich wirst Du hier im Forum zu diesem Thema auch einiges finden.