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


Anmelden zum Antworten