Problem bei Threadübergreifenden Handlungen.

  • VB.NET

Es gibt 51 Antworten in diesem Thema. Der letzte Beitrag () ist von MiniKahn.

    Problem bei Threadübergreifenden Handlungen.

    Guten Tag Community...

    Ich versuche vergebsns schon seit gestern abend von einem Thread aus auf eine textbox zuzugreifen die in einem anderen Thread liegt.
    Ich habe das ganze Forum durchstöbert, jedoch finde ich keine passende lösung die ich hinbekomme!

    VB.NET-Quellcode

    1. Public Class ServerClient
    2. Dim newmessages As New Thread(AddressOf verbindung)
    3. Sub verbindung()
    4. While True
    5. scanMessage()
    6. End While
    7. End Sub
    8. Sub scanMessage()
    9. Dim inStream(10024) As Byte
    10. If stream.CanRead Then
    11. stream.Read(inStream, 0, CInt(Client.ReceiveBufferSize))
    12. Dim returndata As String = _
    13. System.Text.Encoding.ASCII.GetString(inStream)
    14. If returndata.Contains("/NEWS|") Then
    15. Dim ausgabe() As String = returndata.Split("|")
    16. versionstext = ausgabe(1).Replace("~", vbNewLine)
    17. 'MsgBox(versionstext)
    18. Form1.TextBox1.Text = "asd" '<---------
    19. End If
    20. 'MsgBox("Data from Server : " + returndata)
    21. End If
    22. End Sub
    23. End Class


    Ich habe jeglichen Code gelöscht da er eh nie funktioniert hat!
    Ich hoffe ihr könnt mir die nötigen Denkanstöße geben!!!


    lg MiniKahn
    Habe nun GuiHelper eingefügt, und trotzdem will das Script nicht...(unter scanMessage)

    VB.NET-Quellcode

    1. GUIHelper.SetProperty(Form1.newsbox, "Text", versionstext)

    Hab ich eingefügt..
    ( Die newsbox ist wirklich in Class Form1)

    VB.NET-Quellcode

    1. ' Kein Fehler, wenn von einem anderen Thread aufgerufen!
    2. GUIHelper.SetProperty(TextBox1, "Text", "Hallo")

    MiniKahn schrieb:

    Form1.TextBox1.Text = "asd" '<---------

    Das ist wieder der Mist von VB.Net, dass man bei Forms nicht zwischen Klasse und Objekt zu unterscheiden braucht.

    Jedenfalls so lange nicht, bis man ein Form aus einem NebenThread ansprechen möchte ;( .

    Dann wundert man sich u.U. tagelang. gugge auch VeryBasics

    Dein SeverClient sollte nicht versuchen in eine Form1-Instanz hineinzugrabschen, sondern ein Event auslösen, welches in Form1 verarbeitet wird.
    Als invokendes Control kannst du dabei Application.OpenForms(0) nehmen, das ist normalerweise immer verfügbar, solange die App läuft.

    Also wirds erst abschmieren, wenn einer das Form schließt, und der Thread noch läuft, aber da wird dir schon was einfallen.

    Hier stelle ich eine hofflich vollständige Lösung vor, mit Progressbar-Option und der Möglichkeit, während einer nebenläufigen Aktion Controls zu disablen und sowas.

    ErfinderDesRades schrieb:

    Dein SeverClient sollte nicht versuchen in eine Form1-Instanz hineinzugrabschen, sondern ein Event auslösen, welches in Form1 verarbeitet wird.
    Als invokendes Control kannst du dabei Application.OpenForms(0) nehmen, das ist normalerweise immer verfügbar, solange die App läuft.
    Das müsste ich mal probieren, jedoch keine ahnung wie ich mit dem OpenFoms event meine variablebzw meinen Text ändern kann :O



    codeproject.com/KB/vb/AsyncWorker2.aspx
    Verstehe ich leider nicht so wirklich..

    Ich hoffe um weitere hilfe..
    Das schöne an höheren Programmiersprachen ist ja: man muß nicht alles verstehen, ums zu benutzen ;)

    VB.NET-Quellcode

    1. Imports System.Threading
    2. Imports System.Net.Sockets
    3. Public Class ServerClient
    4. Dim newmessages As New Thread(AddressOf verbindung)
    5. Public Event AusgabeChanged As EventHandler
    6. Public Ausgabe As String()
    7. Public Sub OnAusgabeChanged()
    8. RaiseEvent AusgabeChanged(Me, EventArgs.Empty)
    9. End Sub
    10. Sub verbindung()
    11. While True
    12. scanMessage()
    13. End While
    14. End Sub
    15. Sub scanMessage()
    16. Dim inStream(10024) As Byte
    17. If stream.CanRead Then
    18. stream.Read(inStream, 0, CInt(Client.ReceiveBufferSize))
    19. Dim returndata As String = _
    20. System.Text.Encoding.ASCII.GetString(inStream)
    21. If returndata.Contains("/NEWS|") Then
    22. Ausgabe = returndata.Split("|"c)
    23. End If
    24. AsyncWorkerX.NotifyGui(AddressOf OnAusgabeChanged)
    25. End If
    26. End Sub
    27. End Class


    Übrigens: Nie nie nie mit Option Strict Off proggen!

    Und - äh: inStream auf 10024 zu dimensionieren ist eigenartig.
    Üblicher wäre Dim inStream(1023) As Byte, das sind 1024 Bytes.
    Also tut mir leid, ich denke echt das ich solangsam zu blöd für dieses Teil werde...

    Womit hat nun dieser
    AsyncWorkerX zu tun?
    Ist das in Verbindung mit BackgroundWorker?
    Es ist ja das gleiche wie ein Thread, jedoch bleibt ja trotzdem das problem mit der Variabeln-Übergabe..
    Immer wenn ich mit Me.Invoke
    Invoke oder sonstwas arbeiten will, wird angezeigt das es dieses "Invoke" Garnicht gibt..


    Es tut mir echt leid .. :(

    Also ich habe nochmal umgestellt....

    VB.NET-Quellcode

    1. Class Form1
    2. ' Die NewsBox befindet sich hier in dieser Klasse
    3. Dim server As New ServerClient
    4. Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    5. While True
    6. server.client_recieve()
    7. End While
    8. End Sub
    9. End Class
    10. Class ServerClient
    11. Dim news as String
    12. ' Public Sub client_connecten
    13. ' .....
    14. Function client_recieve() As String
    15. client_recieve = streamr.ReadLine
    16. MsgBox(client_recieve)
    17. If client_recieve.StartsWith("/") Then
    18. If client_recieve.Contains("/NEWS|") Then
    19. Dim Ausgabe() As String = client_recieve.Split("|")
    20. news= Ausgabe(1).Replace("~", vbNewLine)
    21. MsgBox(news)
    22. ' Wie bekommen ich nun den String news als den Text von newsbox( newsbox.Text = news)
    23. End If
    24. End If
    25. End Function
    26. End Class


    Bitte macht mir es an einem beispiel von diesem Code klar, BITTEEE :D

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

    MiniKahn schrieb:

    Womit hat nun dieser
    AsyncWorkerX zu tun?

    Er transferiert einen Methoden-Aufruf in den MainThread. Die Methode löst ein Ereignis aus, welches das Form verarbeiten kann. Im Ereignishandler des Forms kannst du die public Variable ServerClient.Ausgabe abrufen, und damit machen, was du möchtest.
    Bin nun am iPod weil ich gleich zur arbeit muss,
    Ich habe aber in Erinnerung das dieser asyncworkerX ist nicht deklariert...
    Wie kann ich das Problem beheben?
    Und durch diese Methode dann kann ich von Form1 per ServerClient.Ausgabe oder in dem Falle mit ein wenig basteln auf ServerClient. News auf die Variable zugreifen?

    Naja bin arbeiten bis 15 Uhr !
    Achso. Du musst "natürlich" das Helpers-Project ausse Codeproject-Solution auch deiner Solution hinzufügen (menu-Datei-Hinzufügen-VorhandenesProject). Und in deinem Startproject einen Verweis darauf setzen (menu-project-eigenschaften-Verweise-hinzufügen-projekte).

    Dann ist AsyncWorkerX deklariert, nämlich in der Helpers-Dll, auf die verwiesen wird.

    Ich empfehle malwieder mein Lieblingsbuch
    Das ist das einzige, wassichkenne, wo sowas auch behandelt wird.

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

    na, wenn du meinen Vortrag schon durcheinanderbringst ;), solltest du auch sagen, wie er das machen soll:

    menu-project-eigenschaften-verweise-hinzufügen-durchsuchen

    und durchsuchen musste die Asyncworker-Solution, nach der "Helpers.Dll"

    Vorteil der Geschichte mit dem Einbinden sind
    1) du kannst später mal verstehen, wies funzt, wenn du mit Generic und Delegaten bekannt bist (s.Buch)
    2) Wenn du selbst mal wiederverwendbaren Code schreiben solltest, kann der auch ins Helpers-Projekt, und von anderen Solutions eingebunden werden.