TCPIP Senden aus Thread in Thread

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    TCPIP Senden aus Thread in Thread

    Hallo*,

    ich habe einen Server auf einer Form(Server) erstellt und dieser funktioniert auch. Nachrichten können an einen Client verschickt und empfangen werden. Wenn ich nun eine bestimmte Nachricht erhalte, soll ein Thread auf einer anderen Form (Form2) gestartet werden und über Invoke Informationen über den Server an den Client verschickt werden. -) funktioniert auch.
    Nun startet der Thread in Form2 einen weiteren Thread in einer anderen Form (Form3), der auch Nachrichten über den Server an den Client verschicken soll und hier fängt das Problem an, dass der Client nicht gefunden werden kann. Ich habe bereits über Invoke versucht die Nachricht zu verschicken, leider ohne Erfolg.
    Hat jemand eine Idee dazu? Geht das überhaupt?

    Zusammen gefasst:
    Programm startet -) Server startet -) Server erhält bestimmte Nachricht und startet Thread in einer anderen Form (Form2) -) Thread aus Form 2 startet Thread in einer anderen (Form3) -) Nachrichten können aus diesem Thread nicht versendet werden.

    Vorab vielen Dank für eure Hilfe
    Ok, zum konkreten Problem kann ich nix sagen. Wenn ich Dich richtig verstehe, hat jedes Form seinen eigenen Weg, um per TCP zu kommunizieren. Aber wenn dem so ist (und so scheint es ja zu sein, wenn es bei dem einen Form geht und bei dem anderen nicht), warum kommunizieren alle 3 Forms nicht mithilfe ein und derselben communication-class-Instanz? Das wäre doch genau deren Aufgabe: »Hey, Com-Klasse, rede Du für uns mit der Außenwelt, wir, die Forms, sagen Dir nur, was Du zu wem zu sagen hast. Aber wie Du mit denen redest, ist uns egal.«
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Genau das mache ich ja, 2 Formen greifen auf die selbe Server Form zu und kommunizieren. Leider geht das nicht aus dem zweiten Thread heraus. Aus dem ersten kann ich über invoke Nachrichten versenden, aber wenn der zweite Thread aus dem ersten startet wird der Client nicht mehr gefunden.

    VB.NET-Quellcode

    1. public class Server
    2. Public Empfangen (text as String)
    3. if text= "123"
    4. Form1.ThreadMessungStarten()
    5. end if
    6. end sub
    7. end class
    8. Public Class Form1
    9. Public Sub ThreadMessungStarten()
    10. ThreadMessung= New.System.threading.thread(Adress of MessungStarten)
    11. ...start
    12. end Sub
    13. Public Sub MessungStarten
    14. ...
    15. settext("TCPIP#123")
    16. ....
    17. Maschine1.ThreadMessungStarten()
    18. ...
    19. 'Warten bis Messung Maschine 1 beendet
    20. end Sub
    21. Public Sub settext (Byval [text] as String)
    22. Dim Befehl() as String = text.split("#")
    23. select case Befehl(0)
    24. case "TCPIP"
    25. Server.AnAllesSenden(Befehl(1))
    26. end select
    27. end Sub
    28. end class
    29. public class Maschine1
    30. Public Sub ThreadMessungStarten()
    31. ThreadMessung= New.System.threading.thread(Adress of MessungStarten1)
    32. ...start
    33. end Sub
    34. Public Sub MessungStarten1
    35. ...
    36. settext("TCPIP#1234") -----------) Geht nicht
    37. ....
    38. end Sub
    39. end class
    40. Public Sub settext (Byval [text] as String)
    41. Dim Befehl() as String = text.split("#")
    42. select case Befehl(0)
    43. case "TCPIP"
    44. Server.AnAllesSenden(Befehl(1))
    45. end select
    46. end Sub
    Entweder ist der Code ausm Kopf geschrieben oder manuell kräftig gekürzt/geändert worden. Denn in einigen Zeilen sind Syntaxfehler, die das Programm nicht starten lassen würden. Daher weiß ich nicht, ob ich überhaupt was zu dem Code sagen soll, wenn dann vielleicht als Antwort kommt: »Naja, nee. Im eigentlichen Programm sieht das ja ganz anders aus. Das läuft da schon, keine Sorge.«

    Aber sei's drum. Aufgrund der Fragmente geht es schon mit Zeile 6 los: Form1.ThreadMessungStarten(), genauso Zeile 29. Da freut sich @RodFromGermany. Denn das geht bei Threading sowas von in die Hose. Daher schrieb ich ja auch was von

    VaporiZed schrieb:

    ein und derselben communication-class-Instanz
    Du hast bei den genannten Zeilen aber nur »Zugriff« auf die gleichen Forms (wenn auch der Zugriff unsauber gestaltet ist). Und eben das funktioniert nicht. Zwei Häuser, die aufgrund des gleichen Bauplans gebaut werden, haben trotzdem zwei unabhängig voneinander zugängliche Briefkästen. Und obwohl alles gleich aussieht, kommt die Post, welches in einen Briefkasten geworfen wird, nicht im zweiten an.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Der Code ist nur runtergeschrieben, damit das Problem halbwegs verständlich dargestellt werden kann, dementsprechend auch nur Fragmente

    Aber sei's drum. Aufgrund der Fragmente geht es schon mit Zeile 6 los: Form1.ThreadMessungStarten(), genauso Zeile 29. Da freut sich @RodFromGermany. Denn das geht bei Threading sowas von in die Hose. Daher schrieb ich ja auch was von


    Warum kann kein Thread so gestartet werden? Was spricht dagegen.

    Du hast bei den genannten Zeilen aber nur »Zugriff« auf die gleichen Forms (wenn auch der Zugriff unsauber gestaltet ist)

    Es klappt doch auch bei Form Server nach Form1 mit Invoke. Sind doch auch zwei verschiedene Forms.
    Dann anders: Dass Du in Server auf Form1 zugreifst, ist vielleicht funktionstüchtig, aber noch lange nicht sauber. Aber das ist ein anderes Thema. Das eigentliche ist, dass Du aus Maschine1 nicht mehr auf dieselben Daten zugreifst, da Du mit Threads arbeitest. Die Server-Klasse greift auf dieselben Daten zu wie Form1. Aber bei Maschine1 geht das nicht, weil Du dann mit »Server« nicht mehr auf dieselbe Serverinstanz zugreifst. Argh. Schwierig, wenn da die Grundlagen fehlen. Ich glaube zumindest, dass es so ist, sonst würde der Code anders aussehen.
    Ok. Stell Dir ein Internetcafé vor. In diesem Internetcafé setzt jemand sich an einen PC und geht ins Internet über einen dort verlegten Internetanschluss. Threading bedeutet auf das Beispiel übertragen, dass gleich neben dran ein 2. Internetcafé des selben Betreibers öffnet und was von der Ausstattung genauso aussieht. Allerdings braucht dieses 2. Internetcafé auch einen Internetanschluss. Es kann aber nicht den von Café 1 benutzen, sondern braucht einen eigenen. Daher kommen Verbindungen von Café 1 an einen Zielcomputer z.B. in Berlin mit anderen Absendedaten als von Café 2. Café 1 und Café 2 sind eben nicht identisch. Sie unterscheiden sich. Und so unterscheiden sich auch die Daten, die hinter »Server« ansprechbar sind, abhängig davon, in welchem Thread sie laufen

    theoretisches Beispiel:
    Thread 1: Wenn man auf die Klasse »Server« zugreift, erhält man für die Variable A den Wert 25
    Thread 2: Wenn man auf die Klasse »Server« zugreift, erhält man für die Variable A den Wert 38
    nur weil »Server« in beiden Fällen genauso heißt, steckt nicht das gleiche drin. Diese Unklarheit/Problematik wird dadurch erst erzeugt, dass VB.Net es (immer noch) ermöglicht, Form-Klassen mit ihren Formnamen anzusprechen, ohne auf eine Instanziierung zu pochen, die jene Unklarheiten von Anfang an vermeiden würde.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Erst einmal vielen Dank für die ausführliche Antwort. Es ist also möglich einen Thread zu erzeugen und über invoke Daten herauszugeben. Wenn nun aber der gleiche Thread einen weiteren Thread (Thread in Thread) erzeugt funktioniert das nicht mehr.
    Wenn ich nun aber doch Daten über den Server aus dem zweiten Thread versenden möchte wäre beispielsweise nur die Möglichkeit my.Settings. Daten zu füllen, einen Timer zu starten (natürlich nicht im zweiten Thread), der dann prüft ob die Variable sich geändert hat und wenn das der Fall ist zu versenden. Ist zwar unschön, aber würde funktionieren oder?

    Bolle schrieb:

    Was spricht dagegen.
    Mit Form1.WhatEver() greifst Du auf die implitite Ranz VB6 mistige Kompatibilitäts-Un-Instanz zu. Gugst Du Dialoge: Instanziierung von Forms und Aufruf von Dialogen um das zu verstehen.
    Gerade bei Threads haut das nicht hin, denn die Ranz-Un-Instanz ist ggf. eine andere als die, die Du siehst.
    Gehe über richtige "Pointer" Me und Du hast weniger Probleme. ;)
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    @Bolle: Puh. Tendenziell eher nein. Die Verwendung der Settings für diesen Zweck stellt eher ein Missbrauch derselbigen dar, da sie für andere Zwecke gedacht ist, nämlich einfaches Speichern von Daten über das Programmende hinaus. Du verwendest sie aber eher als globale Variable. Dafür wäre ein Public Module sinnvoller. Auf dessen Member kann man threadunabhängig zugreifen:

    VB.NET-Quellcode

    1. Public Module TestModule
    2. Public TestVariable As Integer = 0
    3. End Module
    4. Public Class FrmMain
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. TestModule.TestVariable = 1
    7. Dim NewThread As New Threading.Thread(AddressOf TestProcedure)
    8. NewThread.Start()
    9. Do While NewThread.IsAlive
    10. Loop
    11. MessageBox.Show(TestModule.TestVariable.ToString)
    12. End Sub
    13. Private Sub TestProcedure()
    14. TestModule.TestVariable = 2
    15. End Sub
    16. End Class

    Läuft. Es wird 2 angezeigt. Noch besser wäre aber z.B. eine Singleton-Class.

    @RodFromGermany: Das mit dem Me versteh ich in dieser Situation nicht, es geht dem TE ja um Thread- und Form-externe Aufrufe der betroffenen Form.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Bolle schrieb:

    Programm startet -) Server startet -) Server erhält bestimmte Nachricht und startet Thread in einer anderen Form (Form2) -) Thread aus Form 2 startet Thread in einer anderen (Form3) -) Nachrichten können aus diesem Thread nicht versendet werden.
    Klingt mir ganz undurchsichtig und unnütz verwirrend.
    Ich wunder mich schon, dass dein Server überhaupt ein Form hat - eiglich braucht ein Server kein Form.
    Was bedeutet "Server erhält bestimmte Nachricht und startet Thread in einer anderen Form (Form2)"?
    War die andere Form schon da, öffnet "der Server" (wer immer das sein mag) die, und in welchem Thread? und wieso startet der Server überhaupt einen Thread in einer Form??
    Wieso verschickt er die Nachricht nicht selber?

    In meiner Welt wäre sowas möglich:
    es gäbe vlt. ein Form, und das könnte ein Server-Objekt enthalten, evtl. auch einen Singleton. Der Server würde Events feuern, die das Form empfangen kann, und dann tut es etwas.
    Aber wohl weniger direkt auf Nachrichten-Eingang iwas verschicken - da bräuchte ich kein Form für.
    Ein Form hätte Sinn, wenn ein User davor sitzt, und bestimmt, was wann an wen verschickt wird.

    Und bei dir dann nochn Form und nochn Thread und nochn Form und nochn Thread - also durchaus möglich, dass dir niemand dabei helfen kann, einfach weil man da nicht durchblickt

    Bolle schrieb:

    Schließe dann das Thema hiermit.
    Dann musst Du auf das abgerundete Quadrat neben dem Threead-Titel doppelklicken, dann wird der Thread als Erledigt markiert.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!