Thread starten, welcher auf Ereignisse wartet

03/03/2008 - 08:59 von Stephan Glahs | Report spam
Hallo!

Ich habe eine Klasse geschrieben, welche Daten über
die serielle Schnittstelle empfàngt. Sie reagiert auf
das DataRecieved-Ereignis der IO.SerialPort-Klasse.
Ab dem Moment, wo der Empfang stattfindet, wir ein
Timer gestartet, der auf 200Msec. steht. Er wird beim
Empfang von Daten immer wieder zurückgesetzt.
Wenn keine Daten mehr am SerialPort empfangen werden,
löst der Timer aus und wird gestoppt.
Liegen wieder Daten an, geht das ganze von vorn los.
Das ganze dient dazu, das ich ein Ereignis brauchte, welches
eintritt, wenn der Empfang von Daten anfàngt, und ein
Ereigniss, welches auslöst wenn lànger als 200msec keine
Daten auf der Schnittstelle empfangen werden.
Das alles klappt einwandfrei und ist auch für das Problem
an sich irrelevant.

Jetzt zu dem Problem.
Wenn ich diese Klasse aus einer anderen Anwendung heraus
nutze und in dieser kommt es zu einer kurzen "Blockade" aufgrund
einer umfangreicheren Berechnung oder einer Datenbankabfrage,
kann es sein, das der TimeOut-Timer der Klasse feuert, obwohl
Daten an der seriellen Schnittstelle anliegen. Das liegt daran,
das wàhrend der "Blockade" das DataRecieved-Ereignis nicht
abgearbeitet werden konnte und die Zeitüberschreitung der 200
msec stattgefunden hat. Der TimeOut-Timer feuert.

Ich möchte es gern dadurch lösen, das ich alles was in meiner
Klasse stattfindet, in einem eigenen Thread laufen lasse.
Wenn ich aber einen Thread starte, mache ich das ja über die
Adresse einer Methode der Klasse. Es gibt aber keine Methode
in der Klasse, welche dafür in Frage kàme. Die Klasse wartet
eigentlich nur auf Auslösen des DataRecieved Ereignisses und
wàhrenddessen auf Auslösen des TimeOut-Timer.Elapsed
Ereignisses. Erst dort kommt es zum abarbeiten von Daten.
Wo setzte ich mit einem neuen Thread an? Es gibt keine
geschlossene Funktionseinheit dafür.
Ich komme da gedanklich nicht hinter!

Vielen Dank für Hilfe,
Stephan
 

Lesen sie die antworten

#1 Peter Fleischer
03/03/2008 - 14:40 | Warnen spam
"Stephan Glahs" schrieb im Newsbeitrag
news:eQWJ$

Wenn ich diese Klasse aus einer anderen Anwendung heraus
nutze und in dieser kommt es zu einer kurzen "Blockade" aufgrund
einer umfangreicheren Berechnung oder einer Datenbankabfrage,
kann es sein, das der TimeOut-Timer der Klasse feuert, obwohl
Daten an der seriellen Schnittstelle anliegen. Das liegt daran,
das wàhrend der "Blockade" das DataRecieved-Ereignis nicht
abgearbeitet werden konnte und die Zeitüberschreitung der 200
msec stattgefunden hat. Der TimeOut-Timer feuert.



Hi Stephan,
das glaube ich dir nicht. Das DataReceived-Ereignis wird in einem anderen
thread abgearbeitet und unterbricht andere threads, solange diese anderen
threads nicht in einer höheren Prioritàt abgearbeitet werden und permanent
die CPU belegen.

Alternativ bzw. ergànzend kann man auch im Timer-Ereignis abfragen, ob der
SerialPort input buffer nicht leer ist.

Ich möchte es gern dadurch lösen, das ich alles was in meiner
Klasse stattfindet, in einem eigenen Thread laufen lasse.



Das nutzt dir aber nichts. Du solltest besser den Programmablauf prüfen.

Wenn ich aber einen Thread starte, mache ich das ja über die
Adresse einer Methode der Klasse. Es gibt aber keine Methode
in der Klasse, welche dafür in Frage kàme.



Eine Methode kann man problemlos hinzufügen. Das Problem dabei ist aber,
dass die Methode wàhrend der gesamten Arbeitszeit des threads nicht beendet
werden darf, weil mit Ende der Methode auch der thread beendet wird. Das
bedeutet, dass entweder eine Warte-Anweisung oder eine unendliche Schleife
mit Abbruchmöglichkeit und Doevents auszuführen ist.

Eine Wartemöglichkeit gibt es beim SerialPort nur bei ReadLine. Wenn das
aber nicht in Frage kommt, dann bleibt nur die Schleife, die entweder viel
CPU verbraucht oder mit Sleep total lahmgelegt wird. Da das
DataReceived-Ereignis aber in einem anderen thread làuft, wàre ein Sleep
kein Problem. Man könnte das Sleep auch für die Time-Out-Auswertung nutzen.

Die Klasse wartet
eigentlich nur auf Auslösen des DataRecieved Ereignisses und
wàhrenddessen auf Auslösen des TimeOut-Timer.Elapsed
Ereignisses. Erst dort kommt es zum abarbeiten von Daten.
Wo setzte ich mit einem neuen Thread an? Es gibt keine
geschlossene Funktionseinheit dafür.



Ich würde bei diesem Szenario nicht über einen thread nachdenken, da das
DataReceived-Ereignis sowieso in einem eigenen thread làuft. Ich würde die
Klasse mit einer eigenen Puffer-Methode bestücken, die sowohl beim
DataReceived als auch beim ErrorReceived alle Daten aus dem Puffer des
SerialPorts liest und z.B. in einem StringBuilder oder einer List(Of Byte)
ablegt. Sobald ein Zustand eintritt, der aus der Klasse die Benachrichtigung
über das Ende erfordert, z.B. beim Time-Out, kann die Klasse selbst ein
Ereignis auslösen und die im Objekt gepufferten Daten können ausgelesen
werden.

Viele Gruesse

Peter

Ähnliche fragen