Auf ein Ereignis warten ( Visual C# 2005 Express Edition)

Gast #748241
Lesenswert?

Hallo,

ich möchte ein Programm schreiben das Daten über die RS232 an einenen 
Prozessor sendet und dann auf die Antwort wartet. Dann erst soll das 
Programm weiter machen.
Ich habe bereits ein Programm was Daten sendet und auch empfangen kann. 
Über 'serialPort1_DataReceived()' inkl. Threadsicherer Verarbeitung 
klappt das ganze auch soweit. Nur bin ich jetzt mit meinem 
(Anfänger)-Latein am Ende.
Ich möchte im Programm sicher stellen, dass die Antwort auf meine 
Anfrage auch gekommen ist, bevor ich weiter mache.
Es wird wohl irgendwie über Treads gehen. Nur wie kann ich den Thread in 
dem alles läuft anhalten?

Der Ablauf soll in etwa so sein:

1) serialPort1.Write("Hallo");

2) (Warten auf Antwort in 'serialPort1_DataReceived()')

3) Antwort auswerten

4) if(Antwort == ok)
     serialPort1.Write("123");

5) weiter mit 2)

Zur Zeit schreibe ich die Anfragen in einer Funktion untereinander weg 
und werte sie in DataReceived() aus.
Nur sende ich ja die Anfragen hintereinander weg. Und das soll nicht 
sein.

Kann mir da jemand weiterhelfen.

Danke und Grüße
Tobias
#748276
Lesenswert?

Thread ist schon richtig. Dann musst du zuerst ein Event registrieren, 
also der SerialPort komponente bekannt geben, welches Event das 
Empfangs-Event ist. Und dann im Thread einfach WaitOne() mit diesem 
Event benutzen. Dann bleibt der Thread da stehn und macht erst weiter, 
wenn das Event eintritt. Am sinnvollsten nimmt man dafür ein Autoreset 
Event.
Gast #748300
Lesenswert?

Hallo Christian,

das klingt ja ganz einfach und genau nach dem was ich suche.
Nur wie mache ich das Code-Technisch?
Vom logischen verstehe ich deine Antwort zwar, kann sie aber leider 
nicht umsetzen :-(
Kannst Du mir da noch ein wenig unter die Arme greifen?

Tobias
#748350
Lesenswert?

Uff....also Beispielcode hab ich keinen. Einer meiner Hiwis macht das 
momentan für einen CAN-Adapter von IXXAT. Da guck ich immer mal, wie das 
geht.
Zuerst solltest du einfach einen Thread erstellen, wie, steht ja in der 
MSDN Hilfe.
Dann musst du deine Serialport-Klasse hernehmen, wenn´s die aus dem .NET 
Framework ist, gibts ja auch die Anleitung im MSDN. Da halt beim 
Initialisieren das Event registrieren. Das gings mit dem AutoReset 
Event. Such halt mal nach den Begriffen in der MSDN Hilfe. Da findest du 
immer den Beispielcode. im Thread dann einfach WaitOne() aufrufen, als 
Übergabeparameter das Event. Viel mehr kann ich dir leider nicht sagen.
Vielleicht solltest du erst mal einen ganz einfachen Thread 
programmieren, und z.b. mit Thread.Sleep(2000) alle 2000ms irgend ne 
Meldung oder sowas erzeugen, damit du den Mechanismus verstehst.
Gast #2154282
Lesenswert?

Es geht moeglicherweise noch etwas einfacher. Ich habe das eben so 
geloest, dass ich mir in Thread1 eine Methode definiert habe:

private string serialPort1.sendCommand()

Im Thread dieser Methode wird an den serialPort ein Textstring 
geschickt, und laengstenfalls zwei Sekunden auf Antwort gewartet; 
Rueckgabewert ist entweder die Antwort des Ports oder eine 
Fehlermeldung.

Jetzt ists aber so, dass die Variable, die die Antwort des SerialPorts 
enthalten soll, Teil von Thread1 ist, waehrend der serialPort einen 
eigenen Thread (Thread2) darstellt. Aergerlicherweise wird das Event von 
Thread2 erst dann in die Variable geschrieben, wenn Thread1 nicht mehr 
wartet. Ich wollte aber, dass Thread2 die Antwort direkt in die Variable 
schreibt, sobald sie kommt. Die Loesung ist die Befehlszeile:

Application.DoEvents();

Damit haelt Thread1 an und arbeitet alle anderen Events ab, bevor beim 
urspruenglichen Event weitergemacht wird. Komplett sieht die Loesung so 
aus:


  private string serialPortSendCommand(SerialPort p, String str) {
    int timer = 0;
    p.Write(str);

    while(answer == "" && timer < 40) {
      System.Threading.Thread.Sleep(50);
      Application.DoEvents();
      timer++;
    }
    if (timer > 30) return "Error! No Signal!";
    else return answer;
  }
#2154745
Lesenswert?

Peter II schrieb:
> wozu überhaupt threads?
>
>
>  serialPort1.Write("Hallo");
>  serialPort1.Read();
>
> fertig. Die Timeouts kann ma ja auch festlegen - ist das zu einfach oder
> überseh ich was?

Das ist die einfachste Variante. Eleganter ist das über Events zu lösen, 
da das ganze Programm da nicht an einer Stelle wartet. Threads nimmt man 
eher bei Asyncronen Aufgaben.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren