mikrocontroller.net

Forum: PC-Programmierung timer in ereignis starten c#


Autor: Holger74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Floxomat (Gast)
Datum:

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

Autor: Holger74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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));
        }

Autor: Holger74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich möchte DatenPakete mit unterschiedlicher Länge empfangen.

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holger74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soll der Thread im Data_Received-Ereignis gestartet werden?

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger74 schrieb:
> Soll der Thread im Data_Received-Ereignis gestartet werden?

nein, vergiss den Event.

Starte eine extra Methode als Thread.
void Read() 
{
    while( true ) {
        Serial.Read ....
        //verarbeite daten
    }
}

Thread t = new Thread( Read );
t.Start();

(nur schnellt getippt, nicht getestet!)

Autor: Holger74 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!
versuche ich mal.

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Martin Schwaikert (sirnails)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void Read() 
{
    while( true ) {
        Serial.Read ....
        //verarbeite daten
    }
}

Thread t = new Thread( Read );
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?

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.