streamReader.ReadLine abbrechen

  • VB.NET
  • .NET (FX) 4.0

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von phil.

    streamReader.ReadLine abbrechen

    Hallo,

    ich habe einen Server, bei dem in einem Thread auf Nachrichten eines Clients gewartet wird.
    Er wartet beim Abrufen des Streams:

    VB.NET-Quellcode

    1. streamReader.ReadLine()
    Erst wenn eine Nachricht ankommt, wird der Code weiter ausgeführt.


    Wenn ich den Thread jetzt mit thread.abort() abbrechen möchte, reagiert er nicht.

    Hat jemand eine Idee, wie man diesen Thread abbrechen kann?

    phil schrieb:

    wird der Code weiter ausgeführt.
    Kannst Du bitte mal den kompletten Code des Threads posten?
    Wie greifst Du von Deinem Programm aus auf den Server zu?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    VB.NET-Quellcode

    1. Private Sub waitForMessage(ByVal c As Client)
    2. While True
    3. Try
    4. Dim s As String = ""
    5. s = c.streamReader.ReadLine() 'auf Nachricht warten
    6. 's wird verarbeitet und an alle anderen Clients weitergesendet
    7. Catch
    8. 'Berichtet, dass der Client getrennt wurde
    9. Exit While
    10. End Try
    11. End While
    12. End Sub
    Du musst den Thread ja nicht abbrechen (warum überhaupt?). Schreibe doch anstatt t.Abort() myawesomeboolean = True und frage das nach dem einlesen ab. Aber auch das ist nicht die tollste Lösung denke ich.
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
    ich denke, man sollte nicht eine blockierende Schleife in einen NebenThread verlegen, sondern den Vorgang hauptsächlich im Mainthread lassen.
    Nur zum Lesen einer Zeile verwende man Delegate.BeginInvoke(), und im daran anhängigen Callback kann man die nächste Zeile abzurufen beginInvoken - und erhält sowas ähnliches wie eine Ereignis-Kette.

    vlt. programmiert man eine Extra-Klasse, die das handelt, und die bei jeder eingehenden Zeile ein Event feuert.
    Das Event kann man dann ja abbestellen, wenn nicht mehr gewünscht, und auch der Klasse mitteilen: "nicht mehr weiterlesen" - sonst liest die ja trotzdem noch weiter.

    Einen Thread bräuchte man bei diesem Ansatz gar nicht abzuschießen.

    Statt Delegate.BeginInvoke ist vmtl. einfacher, das neue Await-Feature einzusetzen.
    Ich habe es nicht ganz verstanden, :( kannst du bitte ein bisschen Code senden.

    Meinst du, dass nur gelesen wird, wenn etwas kommt, und das dann in einer Schleife abgefragt wird?

    @ThePlexian
    Das Problem ist ja, dass die Ausführung gerade in der .ReadLine drinsteckt. Da kann ich keinen Boolean abfragen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „phil“ ()

    nein, da kann ich dich nicht sinnvoll mit einem Snippet für versorgen.
    Zum einen müsste ich selbst Tests machen, aber ich hab deine Anwendung ja gar nicht.
    Dann müsstest du deine Anwendung ziemlich umbauen, weg von der Schleifen-Denke, hin zur Event-Denke.

    Es ist halt schon eine fortgeschrittene Programmier-Technik, man muss eine Klasse coden können, die ein Event feuert, und man muss sich mit Delegaten, Events und Threading nach dem asynchronen Entwurfsmuster auskennen, sonst kann mans halt nicht umsetzen.
    @phil Gibt es evtl. einen Mechanismus analog zu SerialPort.DataReceived, wo Du ein Event vom Server / ECP-Objekt bekommst, wenn neue Daten vorhanden sind?
    Ich könnte mir auch ein Timer-gesteueertes Polling vorstellen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany
    Ich habe kein schon vorprogrammiertes Event gefunden. (Ich hätte mir vorgestellt, dass es so etwas in der Stream- oder der StreamReader-Klasse gibt)

    @ErfinderDesRades
    Und ich habe auch keinen boolean gefunden, mit dem man abfragen kann, ob eine neue Nachricht angekommen ist.
    Ein eigenes Event würde ich mir folgendermaßen vorstellen:
    In einer Schleife wird immer wieder abgefragt, ob eine Nachricht angekommen ist (dieser boolean). Wenn der true ist, wird ein Event gefeuert.
    Stellst du dir es auch so vor, oder sind wir komplett auf anderen Wegen?

    Klassen, Events und Threading kenne ich.
    Wenn ich den Server beenden will, oder einzelne Clients rausschmeißen will, möchte ich nicht, dass im Hintergrund immer noch Threads weiterlaufen und auf die Clients warten, die ich eigentlich schon rausgeschmissen habe.
    D.h. ich suche irgendeine Möglichkeit, den Thread zu eliminieren.

    phil schrieb:

    Klassen, Events und Threading kenne ich.
    Ja, dann schreib eine Klasse, die ein Event feuern kann, und von der man dann einen Result-String abrufen kann.

    Strukturier deine Anwendung so um, dass du die Klasse etwas senden lassen kannst - mw. mit einem Timer, und dass das dann in deiner Anwendung ankommt.

    wenn das funzt, kann man den Timer-Mock vlt. austauschen durch was, was mit invoking vom StreamReader Zeilen abruft.
    Wenn Du den Server beenden willst, dann nutze die .Stop()-Funktion der TcpListener-Klasse. Hier wird dann eine SockeException geworfen, die Du fangen kannst. Wenn Du nen Client killen willst, dann schick ihm ne Nachricht, dass er sich eben schließen soll.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    @SpaceyX
    .stop() verwende ich schon. Das funktioniert gut.
    Für einzelne Clients habe ich erfolglos versucht: streamReader = nothing. Da wird aber keine Exception geworfen.
    Darauf, dass sich der Client selber schließt, möchte ich nicht vertrauen. :/

    @ErfinderDesRades
    Wie soll ich dann die Codestelle gestalten, die das Event feuert?
    Eine Schleife, die immer überprüft, ob eine Nachricht angekommen ist?
    Das müsste dann auch in einem Thread passieren.

    phil schrieb:

    Das müsste dann auch in einem Thread passieren.

    RodFromGermany schrieb:

    Ich könnte mir auch ein Timer-gesteueertes Polling vorstellen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    phil schrieb:

    Wie soll ich dann die Codestelle gestalten, die das Event feuert?
    Eine Schleife, die immer überprüft, ob eine Nachricht angekommen ist?
    lass es leer.

    Vor allem hör mal mit deinen Schleifen auf. Event-orientiert geht ohne Schleifen.

    Oder: Sagte ich nicht etwas von einem Timer, der fürs erste als Mock herhalten könnte? Wenn der tickt, dann kann deine Klasse doch ihr Event senden.
    Ich habe die Lösung gefunden 8o :

    VB.NET-Quellcode

    1. streamReader.Close()
    Löst eine Exception beim Lesevorgang aus, wodurch der Thread abgebrochen wird.

    Trotzdem großen Dank an euch, dass ihr euch so mit meinem Thema beschäftigt habt.