Stream von Server in TextBox leiten

  • VB.NET
  • .NET (FX) 4.0

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    OK Chef ganz ruhig ;)

    Hab ich gemacht und dabei kam folgende Fehlermeldung: "Der Zugriff auf das Steuerelement RichTextBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstell wurde."

    Das heißt aber doch genau das was fichz gesagt hat oder nicht?


    Edit: Ich habe es selber lösen können mit einem Delegate und Invoke.

    VB.NET-Quellcode

    1. Delegate Sub mainserverCallback(ByVal Args As Object)
    2. Sub mainserver()
    3. Try
    4. Server = New TcpListener(ipendpoint)
    5. Server.Start()
    6. client = Server.AcceptTcpClient
    7. stream = client.GetStream
    8. streamr = New StreamReader(stream)
    9. streamw = New StreamWriter(stream)
    10. Dim i As Boolean
    11. i = True
    12. While (i = True)
    13. Dim SendObject As Object
    14. SendObject = streamr.ReadLine
    15. Me.Invoke(New mainserverCallback(AddressOf ApplyValues), SendObject)
    16. End While
    17. Catch ex As Exception
    18. End Try
    19. End Sub
    20. Private Sub ApplyValues(ByVal Args As Object)
    21. Try
    22. RichTextBox1.AppendText(Args.ToString)
    23. Catch ex As Exception
    24. End Try
    25. End Sub

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Lt.Winters“ ()

    Lt.Winters schrieb:

    Ich habe es selber lösen können
    Schmeiß das Try / Catch ersatzlos raus :!:
    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!
    Na klar, gerne doch ;) Viel Spaß beim Optimieren.

    EDIT: So nun nochmal die Version OHNE TryCatch...damit hier nicht wieder Missverständnisse entstehen.

    VB.NET-Quellcode

    1. 'Version 1.1
    2. Public Class Form2
    3. Dim stream As NetworkStream
    4. Dim streamw As StreamWriter
    5. Dim streamr As StreamReader
    6. Dim Server As TcpListener
    7. Dim client As New TcpClient
    8. Dim ipendpoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 4713)
    9. Dim mainthread As Threading.Thread
    10. Delegate Sub mainserverCallback(ByVal Args As Object)
    11. Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    12. mainthread = New Threading.Thread(AddressOf mainserver)
    13. mainthread.Start()
    14. End Sub
    15. Sub mainserver()
    16. Server = New TcpListener(ipendpoint)
    17. Server.Start()
    18. client = Server.AcceptTcpClient
    19. stream = client.GetStream
    20. streamr = New StreamReader(stream)
    21. streamw = New StreamWriter(stream)
    22. Do
    23. SendObject = streamr.ReadLine
    24. Me.Invoke(New mainserverCallback(AddressOf ApplyValues), SendObject)
    25. Loop
    26. End Sub
    27. Private Sub ApplyValues(ByVal Args As Object)
    28. RichTextBox1.AppendText(Args.ToString & vbCrLf) 'Empfängt Daten vom Endgerät und lädt diese in eine RTB (Delegate und Invoke!)
    29. End Sub
    30. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    31. streamw = New StreamWriter(stream)
    32. Dim Befehl As String = TextBox1.Text
    33. streamw.WriteLine(Befehl) 'Sendet einen Befehl an das Endgerät per StreamWriter
    34. streamw.Flush()
    35. TextBox1.Clear()
    36. End Sub
    37. Private Sub Form2__close(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.FormClosing
    38. Server.Stop()
    39. mainthread.Abort()
    40. End Sub
    41. End Class

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Lt.Winters“ ()

    Bitte kopier den Code genau so rein, wie der bei in der IDE ist.
    Weil das hier kann gar nicht kompilieren.
    Was mir auffällt:
    1. Zusätzlich entferne ALLE Try-Catch Konstrukte, wo keine Ausnahme behandelt wird. Du wirst NIE einen Fehler finden.
    Try Catch verwendet man nur dann wenn etwas unerwartetes passieren kann. Und da catcht man auch nur die Exceptions die man einfach nicht verhindern kann. Zb beim Durchlaufen einer Verzeichnisstruktur auf eine UnauthorizedAccessException.

    2. mainthread.Abort kannst du dir schenken wenn du dem Thread die Property IsBackgroud auf True setzt. Somit wird der Thread beim Beenden der Anwendung mitbeendet.

    3.

    VB.NET-Quellcode

    1. Me.Invoke(New mainserverCallback(AddressOf ApplyValues), SendObject)

    Mach daraus

    VB.NET-Quellcode

    1. Me.Invoke(Sub()
    2. RichTextBox1.AppendText(streamr.ReadToEnd)
    3. End Sub)

    Somit brauchst du keinen Callback und keine ApplyValues Methode.

    4. Steuerelementen anständige Namen geben.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    @EDR: Eigentlich habe ich größten Respekt vor dir und deiner Kompetenz, aber den Kommentar finde ich reichlich mies von dir. Das ist nix weiter als ein billiger CopyPaste-Fehler. Ich musste schließlich Code entfernen, da ich ja hier nicht alles offen legen muss was ich da programmiere. So viel Verständnis hätte ich gerade von DIR schon erwartet. Im Übrigen geht es ja nicht nur um mich, sondern auch darum das hier andere eine Lösung haben.

    Aber um nicht ab zu schweifen und konstruktiv zu bleiben, ich werde den Fehler oben beseitigen.
    ich hätte zu fichz noch zuzufügen:

    VB.NET-Quellcode

    1. 'ersetze
    2. Dim i As Boolean
    3. i = True
    4. While (i = True)
    5. '...
    6. End While
    7. 'durch
    8. Do
    9. '...
    10. Loop


    Bitte einen Boolean nicht ausgerechnet i nennen, und auch einen Boolean nicht mit True vergleichen.
    Denn der Vergleich auch nix anneres als True oder False, und True oder False ist der Boolean ja selber.
    Also einfach

    VB.NET-Quellcode

    1. While i
    2. '...
    wäre angemessener, aber in diesem Falle ja eh nicht.

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

    also aus deim Code sollten die Zeilen #11, 12, 33-35, 49 gelöscht sein

    Edit - jetzt nochmal durchgeflöht:

    VB.NET-Quellcode

    1. Public Class Form2
    2. Dim streamw As IO.StreamWriter
    3. Dim ipendpoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 4713)
    4. Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    5. Dim mainthread = New Threading.Thread(AddressOf mainserver) With {.IsBackground = True}
    6. mainthread.Start()
    7. End Sub
    8. Sub mainserver()
    9. Dim Server = New TcpListener(ipendpoint)
    10. Server.Start()
    11. Dim client = Server.AcceptTcpClient
    12. Dim stream = client.GetStream
    13. Dim streamr = New StreamReader(stream)
    14. streamw = New StreamWriter(stream)
    15. Do
    16. Dim line = streamr.ReadLine
    17. Me.BeginInvoke(Sub() RichTextBox1.AppendText(line & Lf))
    18. Loop
    19. End Sub
    20. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    21. Dim Befehl As String = TextBox1.Text
    22. streamw.WriteLine(Befehl) 'Sendet einen Befehl an das Endgerät per StreamWriter
    23. streamw.Flush()
    24. TextBox1.Clear()
    25. End Sub
    26. Private Sub Form2__close(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.FormClosing
    27. Server.Stop()
    28. End Sub
    29. End Class
    Immer weitestmöglich kapseln: Variablen, die du nur lokal brauchst, auch konsequent nur lokal deklarieren.
    Beachte das mit dem LF - das ist ein LineFeed, wenn man die ControlChars eingebunden hat.
    Dringend empfohlen, die Deppen-Einstellungen rauszuwerfen: Visual Studio - Empfohlene Einstellungen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()