Probleme mit "Threading"

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 41 Antworten in diesem Thema. Der letzte Beitrag () ist von thefiloe.

    Probleme mit "Threading"

    Guten Abend,

    Ich versuche eine Aufgabe in einem neuem Thread auszuführen da ich sonst das Problem habe, das die Form nicht reagiert.
    Allerdings bekomme ich folgende Fehlermeldung vom Debugger.

    Der Zugriff auf das Steuerelement ComboBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.

    Der Code sieht wie folgt aus:

    VB.NET-Quellcode

    1. ​Dim startstream As System.Threading.Thread


    VB.NET-Quellcode

    1. Public Sub Start()
    2. stream = Bass.BASS_StreamCreateURL("http://" + ComboBox1.Text + ".xx", 0, BASSFlag.BASS_STREAM_AUTOFREE, Nothing, IntPtr.Zero)
    3. Bass.BASS_ChannelPlay(stream, False)



    Irgendwelche Tipps?
    Moin,

    Du musst um auf GUI-Elemente zuzugreifen ​Invoke aufrufen.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Glaube das sollte so irgendwie in VB.NET gehen:

    Visual Basic-Quellcode

    1. ​Invoke(Sub()
    2. DeinLabel.Text = "Test" ' Oder was auch immer.
    3. End Sub)


    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Inwiefern nicht? Gibt es einen Fehler? Normal sollte das so über Lambda gehen.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Zeige mal den genauen Fehler und den Code.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Habe einfach dein Code genommen und meinen dazwischen gepackt, der oben schon steht.

    VB.NET-Quellcode

    1. ​ Invoke(Sub()
    2. stream = Bass.BASS_StreamCreateURL("http://" + ComboBox1.Text + ".xx", 0, BASSFlag.BASS_STREAM_AUTOFREE, Nothing, IntPtr.Zero)
    3. Bass.BASS_ChannelPlay(stream, False)
    4. End Sub)


    Sorry wenn ich gerade etwas "dumm" rüberkomme, aber ich habe nie mit Invokes gearbeitet.
    Habe es gerade probiert, bei mir geht das so mit der Syntax. Das Problem muss bei den BASS-Sachen liegen.
    Was genau ist denn der Fehler? Es reicht übrigens, wenn Du die erste Zeile invokest, weil beim zweiten greifst Du nicht mehr auf die GUI zu. ;)

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    TheVBNoob schrieb:

    hakt die GUI
    Welche Möglichkeiten der Wiedergabe bietet denn die Bass.dll an?
    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!
    Das liegt ganz einfach daran, dass wenn du in einem Thread invokst, es synchron ausgeführt wird. Also bringt dir der Thread rein gar nichts, denn alles was darin passiert ist zu invoken. Versuch mal folgendes:

    VB.NET-Quellcode

    1. Dim garcon As String
    2. Invoke(Sub() garcon = ComboBox1.Text)
    3. stream = Bass.BASS_StreamCreateURL("http://" + garcon + ".xx", 0, BASSFlag.BASS_STREAM_AUTOFREE, Nothing, IntPtr.Zero)Bass.BASS_ChannelPlay(stream, False)
    4. Bass.BASS_ChannelPlay(stream, False)
    Mfg
    Vincent

    Bereits in Post#1 sagt die Fehlermeldung doch alles:

    TheVBNoob schrieb:

    Der Zugriff auf das Steuerelement ComboBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
    Also halte dich daran, und grabsche nicht aus dem NebenThread in die Combobox.

    Threading geht so:
    Du bereitest die Daten vor, tust sie in Variablen, Listen, whatever - aber nicht in Comboboxen, Pictureboxen etc, denn das sind ja Controls.
    Dann startest du den Thread, und übergibst die Daten.
    Oder der Thread kann auch die Daten abrufen, aber nicht abrufen aus Comboboxen, Pictureboxen etc, denn das sind ja Controls (nicht vergessen!). Sondern die Daten abrufen aus den dafür geschaffenen Variablen.
    Jo, dann gibts weiter kein Problem, da muss nichtmal Invoked werden.
    Invoken ist erst notwendig, wenn der Thread seine Arbeit getan hat, und seine Ergebnisse zurück-liefern will - das geht ja meist an Controls, weil sonst sieht man die Ergebnisse ja nicht.

    also nochmal:
    1. Daten vorbereiten für den Thread
    2. Thread starten - der verarbeitet dann die Daten - ohne Invoking! - denn Invoking transferiert ja wieder in den Main-Thread, und blockiert den dann ( dein "trotzdem" hakendes Gui)
    3. sind die Ergebnisse fertig - dann einmal Invoken, und zwar eine Methode invoken, die im Gui-Thread dann die Ergebnisse anzeigt.
      und Invoken nicht mit Control.Invoke, sondern mit Control.BeginInvoke.
    Ein wesentlich besserer Ansatz als diese Invokerei ist übrigens der Async-Await-Pattern - aber das bin ich zu faul zu erklären, zumal ich fürchte, dass das Grundlagen-wissen nicht gegeben sind, sprich Umgang mit Delegaten und anonyme Methoden.
    Aber ein Tut dazu kann ich ja verlinken: Async, Await und Task