Thread Denkfehler
-
Also ich hab da wohl einen Denkfehler.
Ich hab einen Thread der für ein Datagrid die Werte berechnet, und eben diese dem Datagrid zuweist. Nun bekommich aber folgende Fehler Meldung:
An unhandled exception of type 'System.ArgumentException' occurred in system.windows.forms.dll
Additional information: Controls created on one thread cannot be parented to a control on a different thread.
der code sieht ungefähr so aus:
public class frmMain : System.Windows.Forms.Form { private System.Windows.Forms.DataGrid dGErgebnisse; private System.Windows.Forms.Button reset; private void berMW_Click(object sender, System.EventArgs e) { t = new Thread( new ThreadStart( this.BerechneErgebnis )); t.Start(); } private void BerechneErgebnis () { DataTable dt; //Berechne irgendwas this.reset.Enable = true; this.dgErgebnis.Datasource = dt; } }
Das komische daran ist, dass es geht den Button zu enablen, aber eben nicht das Datagrid zu füttern.
Wo liegt mein Denkfehler, und wie kann ich das Problem lösen.BerechneErgebnis sollte als Thread laufen, da die Möglichkeit zum Abbruch der Berechnung gegeben sein sollte. Da diese unter Umständen rel lang dauern kann (Mehrere Minuten)
-
Hallo,
die MSDN sagt zum Thema Threadsicherheit des DatGrids
Threadsicherheit Alle öffentlichen statischen Member (Shared in Visual Basic) dieses Typs sind für Multithreadvorgänge sicher. Es wird nicht garantiert, dass alle Instanzenmember threadsicher sind.
Warum lässt du nicht die Berechnungen Asynchron durchführen und setzt die DataSource dann wieder im UI Thread? Wäre m. E. sowieso die sicherere Methode.
Grüße
-
Ich wuerd sagen, die Fehlermeldung sagts ja eh schon: du kannst nicht von einem anderen Thread direkt auf GUI-Elemente eines anderen Threads zugreifen... IIRC
-
Das hab als erstes gehabt, dass ich im UI Thread das DataGrid(DG) aktuallisierte. Hab dazu im Rechen-Thread(RT) ein Event losgelösst, das der RT jetzt fertig ist, und hab das abgefangen, um eben dann das DG zu aktualisieren.
Das gab aber eben die gleiche Fehlermeldung von sich.
-
public class frmMain : System.Windows.Forms.Form { private System.Windows.Forms.DataGrid dGErgebnisse; private System.Windows.Forms.Button reset; private delegate void finishHandler(DataTable data); private void berMW_Click(object sender, System.EventArgs e) { t = new Thread( new ThreadStart( this.BerechneErgebnis )); t.Start(); } private void BerechneErgebnis () { DataTable dt; //Berechne irgendwas finish(dt); } private void finish(DataTable data) { if(InvokeRequired) { this.Invoke(new finishHandler(finish),new object[]{data}); // threads syncronisieren } this.reset.Enable = true; this.dgErgebnis.Datasource = data; } }
-
Ok, wunderbar, das geht.
Hatte da wohl bei meinem Event/Delegate den Denkfehler, bzw hatte ich wohl nicht richtig syncronisert.1000 Dank auf jeden Fall