Ich habe ein Szenario. (Windows Forms, C #, .NET)
- Es gibt ein Hauptformular, in dem einige Benutzersteuerelemente gehostet werden.
- Das Benutzersteuerelement führt einige
UserControl_Load
umfangreiche Datenoperationen aus , sodass die Benutzeroberfläche für die Dauer der Ausführung der Lademethode nicht mehr reagiert, wenn ich die Methode direkt aufrufe. - Um dies zu überwinden, lade ich Daten in einen anderen Thread (versuche, vorhandenen Code so wenig wie möglich zu ändern).
- Ich habe einen Hintergrund-Worker-Thread verwendet, der die Daten lädt und die Anwendung benachrichtigt, wenn sie fertig ist.
- Jetzt kam ein echtes Problem. Die gesamte Benutzeroberfläche (Hauptformular und seine untergeordneten Benutzersteuerelemente) wurde im primären Hauptthread erstellt. In der LOAD-Methode der Benutzersteuerung rufe ich Daten basierend auf den Werten eines Steuerelements (wie z. B. eines Textfelds) in userControl ab.
Der Pseudocode würde folgendermaßen 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 war
Threadübergreifende Operation ungültig: Steuerelement, auf das von einem anderen Thread als dem Thread zugegriffen wird, für den es erstellt wurde.
Um mehr darüber zu erfahren, habe ich ein bisschen gegoogelt und ein Vorschlag kam wie der folgende Code
CODE 2
UserContrl1_LoadDataMethod()
{
if (InvokeRequired) // Line #1
{
this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod));
return;
}
if (textbox1.text == "MyName") // Now it wont 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 ABER ABER ... es scheint, ich bin wieder auf dem ersten Platz. Die Anwendung reagiert erneut nicht mehr. Es scheint an der Ausführung von Zeile 1 zu liegen, wenn Bedingung. Die Ladeaufgabe wird wieder vom übergeordneten Thread ausgeführt und nicht vom dritten, den ich erzeugt habe.
Ich weiß nicht, ob ich das richtig oder falsch wahrgenommen habe. Ich bin neu im Threading.
Wie löse ich das und was bewirkt die Ausführung von Zeile 1, wenn blockiert?
Die Situation ist dies : Ich möchte Daten basierend auf dem Wert eines Steuerelements in eine globale Variable laden. Ich möchte den Wert eines Steuerelements im untergeordneten Thread nicht ändern. Ich werde es nie von einem Kinder-Thread aus tun.
Greifen Sie also nur auf den Wert zu, damit die entsprechenden Daten aus der Datenbank abgerufen werden können.