683 Stimmen

Cross-Thread-Operation nicht gültig: Zugriff auf das Steuerelement von einem anderen Thread als dem, in dem es erstellt wurde

Ich habe ein Szenario. (Windows Forms, C#, .NET)

  1. Es gibt ein Hauptformular, das einige Benutzerkontrollen enthält.
  2. Das Benutzersteuerelement führt einige umfangreiche Datenoperationen durch, so dass ich, wenn ich direkt die UserControl_Load Methode wird die Benutzeroberfläche für die Dauer der Ausführung der Lademethode reaktionslos.
  3. Um dieses Problem zu lösen, lade ich die Daten in einem anderen Thread (und versuche, den bestehenden Code so wenig wie möglich zu ändern)
  4. Ich habe einen Hintergrund-Worker-Thread verwendet, der die Daten lädt und, wenn er fertig ist, der Anwendung mitteilt, dass er seine Arbeit getan hat.
  5. Jetzt kam ein echtes Problem. Das gesamte UI (Hauptformular und seine untergeordneten Benutzerkontrollen) wurde auf dem primären Hauptthread erstellt. In der LOAD-Methode des Benutzersteuerelements rufe ich Daten ab, die auf den Werten eines Steuerelements (z. B. Textfeld) auf userControl basieren.

Der Pseudocode würde wie folgt aussehen:

CODE 1

UserContrl1_LoadDataMethod()
{
    if (textbox1.text == "MyName") // This gives exception
    {
        //Load data corresponding to "MyName".
        //Populate a globale variable List<string> which will be binded to grid at some later stage.
    }
}

Die Ausnahme, die es gab, war

Cross-Thread-Operation nicht gültig: Zugriff auf das Steuerelement von einem anderen Thread als dem, in dem es erstellt wurde.

Um mehr darüber zu erfahren, habe ich ein wenig gegoogelt und einen Vorschlag gefunden, wie man den folgenden Code verwenden kann

CODE 2

UserContrl1_LoadDataMethod()
{
    if (InvokeRequired) // Line #1
    {
        this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod));
        return;
    }

    if (textbox1.text == "MyName") // Now it won't give an exception
    {
    //Load data correspondin to "MyName"
        //Populate a globale variable List<string> which will be binded to grid at some later stage
    }
}

Aber es scheint immer noch so, dass ich wieder am Anfang stehe. Die Anwendung wieder reagiert nicht mehr. Dies scheint auf die Ausführung der if-Bedingung in Zeile 1 zurückzuführen zu sein. Die Ladeaufgabe wird wieder vom übergeordneten Thread ausgeführt und nicht vom dritten Thread, den ich gestartet habe.

Ich weiß nicht, ob ich das richtig oder falsch wahrgenommen habe. Ich bin neu im Threading.

Wie kann ich dieses Problem lösen und welche Auswirkungen hat die Ausführung des if-Blocks in Zeile 1?

Die Situation ist wie folgt : Ich möchte Daten in eine globale Variable laden, die auf dem Wert eines Steuerelements basiert. Ich möchte den Wert eines Steuerelements nicht über den Child-Thread ändern. Ich werde dies niemals von einem Child-Thread aus tun.

Es wird also nur auf den Wert zugegriffen, damit die entsprechenden Daten aus der Datenbank abgerufen werden können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X