Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Control wird von einem anderen Thread aufgerufen?
reteep
myCSharp.de - Member



Dabei seit:
Beiträge: 70
Herkunft: Aschaffenburg

Themenstarter:

Control wird von einem anderen Thread aufgerufen?

beantworten | zitieren | melden

Kompletter Error:
Message: Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.

Der Fehler tritt genau hier auf:


richTextBox1.Text += "ChangeT
ype :: " + e.ChangeType.ToString() + "\nFullPath ::" + e.FullPath.ToString() + "\n\n";

Wenn ich die Zeile einfach in eine string Variable packe gehts, ich möchte es aber direkt in die Textbox parsen. Weis jemand Rat? Danke!

Ich hab das definiert:


        private System.Windows.Forms.RichTextBox richTextBox1;

Und diesen Code:


using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace FolderWatcher_
{
    public partial class Form1 : Form
    {
        private FileSystemWatcher myWatcher;
        private Button btnAddFile, btnAddDir, btnDelDir, btnDelFile, btnExit;
        string DirPath;

        public Form1(string myPath)
        {
            DirPath = myPath;
            InitializeComponent();
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            myWatcher = new FileSystemWatcher(DirPath);
            myWatcher.EnableRaisingEvents = true;
            myWatcher.IncludeSubdirectories = true;
            myWatcher.Created += new FileSystemEventHandler(myWatcher_Created);
            myWatcher.Changed += new FileSystemEventHandler(myWatcher_Changed);
            myWatcher.Deleted += new FileSystemEventHandler(myWatcher_Deleted);
            myWatcher.Renamed += new RenamedEventHandler(myWatcher_Renamed);
        }

        public static void Main()
        {
            myProperties myprop = new myProperties();
            myprop.ShowDialog();
            Application.Run(new Form1(myprop.myPath));
        }
        
        //Creating New File
        protected void btnAddFile_Click(object sender, EventArgs e)
        {

        }

        // Created Event
        protected void myWatcher_Created(object sender, FileSystemEventArgs e)
        {
            richTextBox1.Text += "ChangeType :: " + e.ChangeType.ToString() + "\nFullPath ::" + e.FullPath.ToString() + "\n\n";
        }

        //Changed Event
        protected void myWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            richTextBox1.Text += "ChangeType :: " + e.ChangeType.ToString() + "\nFullPath ::" + e.FullPath.ToString() + "\n\n";
        }

        //Deleted Event
        protected void myWatcher_Deleted(object sender, FileSystemEventArgs e)
        {
            richTextBox1.Text += "ChangeType :: " + e.ChangeType.ToString() + "\nFullPath ::" + e.FullPath.ToString() + "\n\n";
        }

        //Renamed Event
        protected void myWatcher_Renamed(object sender, RenamedEventArgs e)
        {
            richTextBox1.Text += "ChangeType :: " + e.ChangeType.ToString() + "\nFullPath ::" + e.FullPath.ToString() + "\nOld FileName :: " + e.OldName.ToString() + "\n\n";
        }
    }
}
private Nachricht | Beiträge des Benutzers
Dan
myCSharp.de - Member



Dabei seit:
Beiträge: 124
Herkunft: Munich

beantworten | zitieren | melden

Hi,

von einem anderen Thread kann man nicht auf die User Controls zugreifen, dafür musst du
Control.Invoke oder Control.BeginInvoke aufrufen.

Statt der Zuweisung:

richTextBox1.Text += "...";

solltest du nen Delegate erstellen und prüfen ob ein Invoke erforderlich ist.
z.B. so:


private delegate void AppendTextHandler(string s);

private void AppendText(string s)
{
 if( richTextBox1.InvokeRequired )
  richTextBox1.Invoke(new AppendTextHandler(AppendText), new object[]{s});
 else
  richTextBox1.Text += s;
}
private Nachricht | Beiträge des Benutzers
reteep
myCSharp.de - Member



Dabei seit:
Beiträge: 70
Herkunft: Aschaffenburg

Themenstarter:

beantworten | zitieren | melden

Ok danke so hats geklappt:


        protected void myWatcher_Created(object sender, FileSystemEventArgs e)
        {
            //FileStream file = new FileStream("change.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
            //StreamWriter sw = new StreamWriter(file);
            //sw.Write("ChangeType :: " + e.ChangeType.ToString() + "\nFullPath ::" + e.FullPath.ToString() + "\n\n");
            //sw.Close();

         string s = "ChangeType :: " + e.ChangeType.ToString() + "\nFullPath ::" + e.FullPath.ToString() + "\n\n";
            AppendText(s);
        }                       

            private delegate void AppendTextHandler(string s);

            private void AppendText(string s)
            {
            if( richTextBox1.InvokeRequired )
            richTextBox1.Invoke(new AppendTextHandler(AppendText), new object[]{s});
            else
            richTextBox1.Text += s;
            }
private Nachricht | Beiträge des Benutzers
alf468
myCSharp.de - Member



Dabei seit:
Beiträge: 196

beantworten | zitieren | melden

Seit dem Umstieg auf .NET 2 kommt bei mir auch immer dieser Fehler
Zitat
Cross-thread operation not valid:

Ich will aber nicht meinen ganzen Quellcode umschreiben. Gibt es keine schnellere Möglichkeit außer invoke() und delegate ?
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo alf468,

das die Exception bei 1.1 nicht kommt, ist ein Bug von 1.1. Stattdessen können bei 1.1 lustige Effekte auftreten. Es kann sein, dass diese Effekte nur unter bestimmten Bedingungen auftreten (Racing Conditions). Dein Code ist also fehlerhaft (auch wenn du keine Exception bekommst und auch wenn die Effekte nicht auftreten). Die einige Lösung ist den Code umzuschreiben. Zum Trost: Invoke ist simpel.

herbivore
private Nachricht | Beiträge des Benutzers
Natsukawa
myCSharp.de - Member



Dabei seit:
Beiträge: 20

beantworten | zitieren | melden

Hallo,

Nach der Umstellung auf .Net 2.0 kam bei mir genau die gleiche Fehlermeldung. Also habe ich auch die Delegates und Invokes eingebaut. Mein Problem ist jetzt, dass die Invokes erst ausgeführt werden,w enn der Thread beendet ist. Das hat zur Folge, dass alle Nachrichten die ich in einem Fenster ausgeben wollte, erst ganz am Ende angezeigt bekomme. Damit fehlen dem Nutzer genau die Rückmeldungen, um die es mir dabei ging. Hat jemand ne Idee, was ich daran ändern muss.

Natsukawa
private Nachricht | Beiträge des Benutzers
Fil
myCSharp.de - Member



Dabei seit:
Beiträge: 234

beantworten | zitieren | melden

Kannst Du mal ein Code-Beispiel posten ?
Oder hast Du das vielleicht blockierend programmiert ?
D.h.: wartet Dein "Haupt"-Thread bis der andere Thread, aus dem die Nachrichten kommen, tot ist? Dann wärs klar, warum.
private Nachricht | Beiträge des Benutzers
Natsukawa
myCSharp.de - Member



Dabei seit:
Beiträge: 20

beantworten | zitieren | melden

Hallo,

Ja der Hauptthread muss auf die anderen Threads warten. Das liegt daran, dass zwischendurch einige Aufgaben parallel in den Threads laufen, und danach der Hauptthread etwas auswerten muss.

Beispiel posten ist etwas schwierig, es verteilt sich auf viele Klassen und so.

Wieos muss den der Hauptthread beendet sein, damit die Nachrichten zur Control durchgereicht werden?

Natsukawa
private Nachricht | Beiträge des Benutzers
der Marcel
myCSharp.de - Member

Avatar #avatar-1860.gif


Dabei seit:
Beiträge: 564
Herkunft: Dresden

beantworten | zitieren | melden

hi!

dein Problem ist folgendes: Wenn ei Thread auf einen anderen wartet, dann ist der wartende Thread blockiert. Als Lösung würde sich anbieten, erst einen "zwischenthread" zu starten, welcher deinen eigentlichen Arbeitsthread aufruft und auf ihn wartet. Per Events müssen die Daten aus deinem eigentlichen Arbeitsthread in den GUI-Thread gelangen. Insgesamt wären das bei der Lösung also 3 Threads. (GUI + Zwischenthread + Arbeitsthread)

der Marcel
:] :DDer größte Fehler eines modernen Computers sitzt meist davor :]
private Nachricht | Beiträge des Benutzers
Fil
myCSharp.de - Member



Dabei seit:
Beiträge: 234

beantworten | zitieren | melden

Nee, der muss nicht beendet sein. Geht ja auch nicht. Er darf nicht blockiert werden. Also ich mein jetzt der Thread in dem die GUI läuft, der darf nicht blockiert werden, sonst passiert da garnichts. Der hängt dann an der Stelle, wo er drauf wartet, daß die anderen Thread zurückkommen. Und erst wenn DIE ihre Arbeit beendet haben, dann läuft er weiter.
Um das zu verhindern, musst Du das mit Threads also so programmieren, daß sie den GUI-Thread nciht blockieren. Das reicht ja, wenn die sowas wie ein "ich bin fertig"-Event schicken. Oder per BeginInvoke und Callback ihr Ergebnis abliefern. Und wenn alle Threads das gemacht haben, wird ausgewertet.

Haha, zwei Dumme, ein Gedanke. Warst schneller, Marcel
private Nachricht | Beiträge des Benutzers
Natsukawa
myCSharp.de - Member



Dabei seit:
Beiträge: 20

beantworten | zitieren | melden

Hallo,

Danke, dass mit dem Bin-Fertig-Event werd ich gleich mal probieren.

Natsukawa
private Nachricht | Beiträge des Benutzers
alf468
myCSharp.de - Member



Dabei seit:
Beiträge: 196

beantworten | zitieren | melden

Hallo ich habe eine kleines Problem.Ich will ein Item in einer Listbox einfügen.
Dabei kommt folgender Fehler:
System.InvalidOperationException: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

Die Listbox ist static hat das Problem damit was zu tun ?
Das ist das erste Mal das ich damit Probleme habe
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo alf468,

es ist so wie die Meldung sagt.

Der Handle eines Controls wird erst bei Show oder explizit durch CreateHandle/Handle erzeugt.

herbivore
private Nachricht | Beiträge des Benutzers