Ungültiger threadübergreifender Vorgang

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von seh.

    Ungültiger threadübergreifender Vorgang

    Hallo Community,

    ich bin gerade leicht am verzweifeln weil ich für diesen Fehler:
    (Anhang) - Keine Lösung finde.

    Fehler tritt hier auf:

    C#-Quellcode

    1. public void addItem(bool system, string cmd)
    2. {
    3. flowLayoutPanel1.VerticalScroll.Value = 0;
    4. log l = new log(system, cmd);
    5. flowLayoutPanel1.Controls.Add(l);
    6. flowLayoutPanel1.ScrollControlIntoView(l);
    7. l.Top = poss;
    8. l.Left = 50;
    9. poss = poss + 50;
    10. }


    und addItem wird hier aufgerufen:

    C#-Quellcode

    1. private void Client_OnConnected(object sender, OnConnectedArgs e)
    2. {
    3. new Thread(() => { addItem(true, "Verbindung konnte hergestellt werden"); }).Start();
    4. }
    5. private void Client_OnConnectionError(object sender, OnConnectionErrorArgs e)
    6. {
    7. new Thread(() => { addItem(true, "Verbindung konnte nicht hergestellt werden"); }).Start();
    8. }


    Es wäre sehr lieb, wenn man mir hier helfen könnte, da ich aktuell verzweifel. :)
    Vielen Dank!

    Fehler ist angehangen.

    Mit freundlichen grüßen
    Kenox
    Bilder
    • O8yYDOrvSbieO6yUNKrd7g.png

      5,33 kB, 599×104, 90 mal angesehen
    Die Fehlermeldung sagt schon alles aus. Du darfst außerhalb des Mainthreads ein CE nicht ändern. Und genau das versuchst Du mithilfe Deiner Client_OnConnected-Prozedur. Es steht ja auch explizit in Deinem Code: new Thread(). Das geht so nicht. Du musst quasi darum bitten bzw. es veranlassen. Stichwort Invoke. Zahlreiche sinnvolle Ergebnisse in der Forensuche. Genauso wie für die Fehlermeldung ...
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hmm, irgendwie komm ich da gerade nicht so durch.
    Wie kann man über z.B ​Client_OnConnected einen Invoke machen, sodass die Funktion "addItem" funktioniert?

    mfg
    Gar nicht. Die Invoke-Methode ist eine CE-(CE=control element = Steuerlement)Methode und gehört somit zum Steuerelementaufruf, also in Deine Prozedur addItem.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    seh schrieb:

    Schau dir Control.Invoke() an.
    Wie soll er sich "Control.Invoke" anschauen? Gibts da iwo Bilder von?
    Und wenn ja, was hat man davon, sich Bilder von "Control.Invoke" anzuschauen?

    Lange Rede kurzer Sinn: Magst du vlt. in einer für Anfänger verständlichen Form präzisieren, was du mit "Control.Invoke() anschauen" eiglich meinst?
    Sonst wird dein Tipp für Kenox kaum hilfreich sein können, denke ich mal.
    @ErfinderDesRades Ich habe nie irgendwas von Bildern erwähnt. Man kann Dokumentationen, so wie ich sie jetzt hier meinte, und was ich eigentlich für sehr logisch und selbstverständlich halte, genauso anschauen. Wenn man nur Control.Invoke bei Google eingibt ist das erste Ergebnis schon die Dokumentation für diese Funktion. Und ganz nebenbei, wenn man dann unter Google Bilder geht, sieht man wie man das ganze anwendet. Also ein wenig Eigeninitiative sollte hier schon vorhanden sein.
    @seh Ich denke auf was man raus wollte war, als Antwort einfach 5 Wörter hinklatschen und gut, ist ja mal nicht unbedingt die Art wie man versucht zu Helfen.
    Hier ist noch Luft nach oben, du hast es sicher gut gemeint, aber wenn du schon so wenig schreiben möchtest hättest du wenigstens zu einem Beispiel verlinken können und/oder ein kleines Beispiel Spoilern können.

    Genauso gut könnte man ja bei JEDEM Thread schreiben "Lese die MSDN und lerne programmieren" :evil:

    Verstehst du auf was man raus will?

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Ich bin jetzt nicht so einer der nach Code schnorrt, aber ich habe das jetzt gerade nochmal angeschaut (msdn.microsoft.com/de-de/library/zyzhdc6b(v=vs.110).aspx)
    und verstehe das ehrlich gesagt überhaupt nicht. Bisher weiß ich, dass ich in der "addItem"-Methode etwas Invoken (?) soll. Aber wie, leider keine Ahnung.

    Könnt ihr mir da weiterhelfen?
    Was genau verstehst du denn nicht ? In deinem Link steht doch genau beschrieben was du machen musst.
    Es bringt ja nichts dir nun deinen fertigen Code hier hin zu schreiben so das du ihn kopierst und immer noch
    nicht verstehst.

    Wäre also Hilfreich zu wissen was genau dir unklar ist an dem MSDN Beispiel ? Denn dann könnten wir versuchen
    dir das nochmal anders zu erklären.
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen

    Kenox schrieb:

    etwas Invoken
    bedeutet, dass Du einen Zugriff, Vorgang, Prozess in einem anderen Thread stattfinden lässt.
    Zugriffe auf GUI-Controls müssen im GUI-Thread stattfinden, sonst gibt es Verwicklungen, wenn von zwei Threads gleichzeitig auf das selbe Control schreibend zugegriffen wird.
    Üblicherweise geht das so:

    C#-Quellcode

    1. private void InvokeLabelTextChange(string txt)
    2. {
    3. if (this.InvokeRequired)
    4. {
    5. // ruft sich selbst auf
    6. this.Invoke(new Action<string>(InvokeLabelTextChange), txt);
    7. return;
    8. }
    9. this.label1.Text = txt;
    10. }
    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!
    @xChRoNiKx Ehrlich gesagt verstehe ich es schneller durch einen fertigen Code. Aber dafür habe ich nicht gefragt.

    Bisher habe ich das:

    C#-Quellcode

    1. public void addItem(bool system, string cmd)
    2. {
    3. flowLayoutPanel1.VerticalScroll.Value = 0;
    4. log l = new log(system, cmd);
    5. //flowLayoutPanel1.Controls.Add(l);
    6. l.Invoke(new Action(() => flowLayoutPanel1.Controls.Add(l)));
    7. ...
    8. }


    Aber da kommt der Fehler: Anhang

    Ich bitte euch mir nicht zu schreiben, dass man es bereits aus dem Fehler entnehmen kann.
    Selbst die Exception verstehe ich nicht, Was ist ein Fensterhandle und wie erstelle ich das zuerst?

    Danke euch! :)
    Bilder
    • O8yYDOrvSbieO6yUNKrd7g.png

      5,33 kB, 599×104, 76 mal angesehen
    @Rod: oh - bitte nicht schon wieder diese Selbst-Aufruf-Infektion verbreiten! Ein Selbst-Aufruf mit Selbst-Test ist nicht nötig, wenn von vornherein klar ist, dass der Selbst-Test positiv sein wird.
    Und Control.Invoke ist auch nur die 2.beste Lösung - aus irgendwelchen Gründen aber ständig dem BeginInvoke vorgezogen.
    Hier meine Einlassung dazu: Controls Threadsicher machen

    @Kenox: Fehlerzeile? (gerne gugge auch mal Exceptions, und was sie uns sagen wollen

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

    Vielen Dank an @RodFromGermany und @ErfinderDesRades für eure Erklärungen.

    Tut mir leid @ErfinderDesRades. Du hast natürlich Recht, das war die Zeile mit dem l.Invoke
    Aber das ist nicht mehr nötig. Da ich das durch euch beiden jetzt verstanden habe.

    Habe auch Control.Invoke zu Control.BeginInvoke geändert, da ja sonst anscheinend
    ein Nebenthread blockiert wird (?).

    mfg

    seh schrieb:

    @ErfinderDesRades Ich habe nie irgendwas von Bildern erwähnt. Man kann Dokumentationen, so wie ich sie jetzt hier meinte, und was ich eigentlich für sehr logisch und selbstverständlich halte, genauso anschauen. Wenn man nur Control.Invoke bei Google eingibt ist das erste Ergebnis schon die Dokumentation für diese Funktion.
    Ja, für dich mag das sonnenklar sein, dass "Control.Invoke() anschauen" bedeutet: 'den Begriff "Control.Invoke()" googeln'.
    Aber Kenox (und ich übrigens auch) verstehn unter "Anschauen" eben vlt. nicht unbedingt: "googeln".
    Dann sag doch lieber, er soll den Begriff googlen, wenn du meinst, er solle ihn googeln.

    Auch das mit den Dokumentationen mag dir klar sein (mir ist es das nicht - ich kenne 2 ganz verschiedene Dokumentationen, und in der einen - MSDN - findet man ohne Googles Hilfe garnix).
    Jdfs. Google kann man ja wohl kaum als "Dokumentation" bezeichnen - das ist eine Suchmaschine, da findest du auch Unterwäsche und - vor allem - Amazon-Reklame.
    Und Kenox kann das alles als Anfänger eiglich unmöglich wissen - Eigeninitiative hin oder her.

    Ich trete das jetzt nur deshalb breit, weil solche Posts oft vorkommen, mit "schau mal [...] an" - und ich krieg da immer stellvertretend für den armen Fragesteller die Krise.



    Nebenbei: Wie gesagt, ich kenne 2 Dokumentationen (des Frameworks), eine davon hab ich verraten: MSDN, unter Zuhilfenahme von Google.
    Kennst du die andere? Oder überhaupt: Welche Dokumentationen kennst du (vlt sind welche dabei, die ich nicht kenne)?

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

    @ErfinderDesRades Ich habe verstanden, dass man sich anscheinend mehr Mühe geben muss einen Beitrag zu formulieren damit auch jeder versteht was damit gemeint war, sogar für Menschen wie dich mit 31000+ Beiträgen und 4300 Hilfreich Bewertungen. Sorry aber ich habe bereits geschrieben, dass ich zu diesem Zeitpunkt nicht viel Zeit hatte und lediglich das Stichwort in den Raum werfen wollte. Das ist kein One-Answer Forum wo nur einer schreiben kann sondern mehrere. Wenn also weitere Erklärungen notwendig wären, dann können gerne andere User erklären wie man Google nutzt, dafür bin ich nicht hier.

    seh schrieb:

    anscheinend mehr Mühe geben muss einen Beitrag zu formulieren damit auch jeder versteht was damit gemeint war
    Das Problem besteht darin, dass der Problembeschreiber zunächst der einzige ist, der das Problem kennt. Das bedeutet noch lange nicht, dass er es auch beschreiben kann.
    Und erst recht nicht so, dass es die anderen verstehen.
    Und schon gar nicht, dass die anderen es so verstehen, wie er es gemeint hat.
    Weil das so ist, kommt hier des öfteren der Begriff "Glaskugel" vorbei, das bedeutet, dass die Problembeschreibung suboptimal war.
    Der @ErfinderDesRades weiß das sehr wohl, deswegen stellt er auch präzise Fragen, um das Problem scharf herauszuarbeiten.
    Das Hineinwerfen eines Stichworts ist da nicht unbedingt hilfreich.
    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!