Forum: PC-Programmierung timer in ereignis starten c#


von Holger74 (Gast)


Lesenswert?

Hallo,
gibt es einen Grund, weshalb sich ein Timer hier nicht starten läßt?

 //empfangene Daten sammeln
 private void serialPort1_DataReceived(object sender, 
serialDataReceivedEventArgs e)
{
 timer2.Enabled= true;
 addToTextBox("daten empfangen\r\n");
}

//Timer2 Auswertung
private void timer2_Tick(object sender, EventArgs e)
{
 timer2.Enabled= false;
 addToTextBox("Timer2\r\n");
}

Von anderen Stellen im Programm gestartet, läuft der Timer wie erwartet.

von Floxomat (Gast)


Lesenswert?

serialPort1_DataReceived wird aus einem anderen Thread heraus 
aufgerufen. Ich gehe davon aus, dass der System.Windows.Forms.Timer das 
nicht mag.

von Holger74 (Gast)


Lesenswert?

Danke :)
selbst wenn man per Hand einen neuen Timer anlegt funktioniert es nicht.

        //empfangene Daten        ----- DataReceived ----
        private void serialPort1_DataReceived(object sender, 
SerialDataReceivedEventArgs e)
        {
         //if (timer2.Enabled== false)
            Timer timerDR = new Timer();
            timerDR.Interval = 100;
            timerDR.Tick += new EventHandler(timerDR_Tick);
            timerDR.Start();

          //timer2.Enabled= true;
          //timer2.Start();
          dataEmpfCnt++;
         addToTextBox(String.Format("daten empfangen 
{0}\r\n",dataEmpfCnt));
        }

von Holger74 (Gast)


Lesenswert?

ich möchte DatenPakete mit unterschiedlicher Länge empfangen.

von Peter II (Gast)


Lesenswert?

Holger74 schrieb:
> ich möchte DatenPakete mit unterschiedlicher Länge empfangen.

und wozu brauchst du da den timer?


Vermutlich ist es für dich viel einfacher einen thread zu starten und 
dort mit Read vom SerialPort zu lesen. Dann kann man auch einen Timeout 
festlegen.

von Holger74 (Gast)


Lesenswert?

Soll der Thread im Data_Received-Ereignis gestartet werden?

von Peter II (Gast)


Lesenswert?

Holger74 schrieb:
> Soll der Thread im Data_Received-Ereignis gestartet werden?

nein, vergiss den Event.

Starte eine extra Methode als Thread.
1
void Read() 
2
{
3
    while( true ) {
4
        Serial.Read ....
5
        //verarbeite daten
6
    }
7
}
8
9
Thread t = new Thread( Read );
10
t.Start();

(nur schnellt getippt, nicht getestet!)

von Holger74 (Gast)


Lesenswert?

Danke!
versuche ich mal.

von c-hater (Gast)


Lesenswert?

Holger74 schrieb:

> selbst wenn man per Hand einen neuen Timer anlegt funktioniert es nicht.

Weil dem Timer scheissegal ist, auf welche Art er erzeugt wird. Der 
springende Punkt ist: er funktioniert eben nur im GUI-Thread der 
Anwendung.

Wenn du einen Timer willst, der unabhängig vom GUI funktioniert, darfst 
du nicht den aus System.Windows.Forms nehmen, den du derzeit verwendest. 
Statt dessen z.B. System.Threading.Timer. Der wird allerdings ganz 
anders benutzt als der, den du kennst. Und natürlich lauft auch dessen 
Event im Kontext eines Nicht-GUI-Threads ab, du kannst also nicht 
einfach in dessen Eventhandler irgendwas am GUI machen.

Die Alternative ist, den Eventhandler des SerialPort mit dem GUI-Thread 
zu synchronisieren, dann kannst du ganz normal mit einem "normalen" 
Timer interagieren. Dazu bietet System.Windows.Forms.Form die netten 
Methoden InvokeRequired, und Invoke bzw. BeginInvoke an.

von Martin S. (sirnails)


Lesenswert?

c-hater schrieb:
> Und natürlich lauft auch dessen
> Event im Kontext eines Nicht-GUI-Threads ab, du kannst also nicht
> einfach in dessen Eventhandler irgendwas am GUI machen.

Das sollte aber nicht das Problem sein - dafür gibt es die BeginInvoke 
Methode.

Man sollte aber nie vergessen, dass der GUI Thread einfach ein eigener 
Thread ist, und der prinzipiell IMMER sehr allergisch darauf reagiert, 
wenn dort ein threadübergreifender Zugriff stattfindet. Es gibt da 
leider sehr oft die Konstellation, dass es 1000x geht, und beim 1001x 
dann nicht.

von Thorsten (Gast)


Lesenswert?

1
void Read() 
2
{
3
    while( true ) {
4
        Serial.Read ....
5
        //verarbeite daten
6
    }
7
}
8
9
Thread t = new Thread( Read );
10
t.Start();

Der Empfang der seriellen Daten ist schon in einem eignen Thread, wieso 
dann noch ein Thread darüber.

Beispiel für Invoke in meinem Beispielprogramm hier:

Beitrag "Visual Studio C# Serielle Daten anzeigen /verstehe befehle nicht"

In der SerialPortKlasse besitzt schon einen Transmit and Receive Timeout 
timer. Magst Du diesen nicht benutzen?

von Peter II (Gast)


Lesenswert?

Thorsten schrieb:
> Der Empfang der seriellen Daten ist schon in einem eignen Thread, wieso
> dann noch ein Thread darüber.

nur wenn man die Events verwende.

> In der SerialPortKlasse besitzt schon einen Transmit and Receive Timeout
> timer. Magst Du diesen nicht benutzen?
genau das soll er ja machen, dafür muss er ja das Read machen, sonnst 
kommt es zu keinem timeout. Event macht das keinen sinn, weil man dort 
nur die Daten abrufen sollte, die vorhanden sind. Damit kommt aber kein 
Timeout mehr.

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
Noch kein Account? Hier anmelden.