Frage

Ich verstehe, wie Sie Delegierten verwenden, um Steuerelemente im Hauptsteuerungs -Thread zu aktualisieren, funktioniert wie ein Zauber. Mein Problem hier ist, wenn ich eine große hinzufüge DataSet (Sagen Sie 2000 Artikel) zu einer Grenze DataGridView, Es dauert 5-8 Sekunden, bis das Netz besiegt wird, und während dieser 5-8 Sekunden ist die gesamte GUI gesperrt. Wie kann ich das aktualisieren DataGridView So dass es die Benutzeroberfläche nicht sperrt?

Um klar zu sein, das Problem ist nicht, dass ich eine langsame Abfrage in eine Datenbank mache und die Benutzeroberfläche blockiert, ich habe bereits das DataSet object[] und Hinzufügen der Objektarray zu a BindingList<object> was die DataGrid ist an so gebunden:

BindingList<object> dataProvider = new BindingList<object>();
DataGridView gridView = new DataGridView();
gridView.DataSource = dataProvider;

// ...stuff happens...

object[] source = dataSet; //of 2000 items
foreach (object item in source) {  //this foreach blocks
    dataProvider.Add(item);
}

Ich habe verschiedene Dinge ausprobiert (von denen ich wusste dataProvider.Add(), Aber das war egal, da es immer noch im Kontrollfaden passieren musste.

Ein paar gute Vorschläge drehten sich darum, das zu bauen BindingList zuerst und dann das festlegen gridView.DataSource. Während dies funktioniert (es aktualisiert das Netz sofort), besteht die einzige Möglichkeit, weitere Daten hinzuzufügen, darin, ein weiteres neues zu erstellen BindingList, machen a gridView.DataSource.copyTo() (Um die vorhandenen Daten zu erhalten) und fügen Sie die neuen Daten darüber hin gridView.DataSource zum neuen BindingList. Dies funktioniert für mich nicht, da die Objekte in meiner Liste nicht statisch sind, sie werden jeweils asynchron auf einen Server hochladen und sie auf einen neuen kopieren BindingList würde Probleme verursachen.

War es hilfreich?

Lösung

Sie fügen Datensätze hinzu, während die GridView mit der Datenquelle verknüpft ist. Dies bedeutet, dass das Layout jedes Mal aktualisiert wird.

Wie wäre es, wenn Sie zuerst Ihre DataSource füllen und erst dann die DataSource -Eigenschaft festlegen?

gridView.DataSource = null;
...stuff happens...

object[] source = dataSet; //of 2000 items
foreach (object item in source) {  //this foreach blocks
    dataProvider.Add(item);
}

gridView.DataSource = dataProvider;

Die Foreach -Loop könnte zu einem anderen Thread gehen, aber ich glaube nicht, dass Sie das brauchen werden.

Andere Tipps

Wie Nick sagte BackgroundWorker ist wahrscheinlich die beste Wahl.

Hier ist ein sehr einfaches Beispiel

public partial class Form1 : Form
{
    BackgroundWorker b = new BackgroundWorker();

    public Form1()
    {
        InitializeComponent();
        b.RunWorkerCompleted += new RunWorkerCompletedEventHandler(b_RunWorkerCompleted);
        b.DoWork += new DoWorkEventHandler(b_DoWork);
    }

    void b_DoWork(object sender, DoWorkEventArgs e)
    {
        // build dataset here and assigning it to results
        e.Result = dataset;            
    }

    void b_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // assign the dataset you built in DoWork in the gridview and update it
        dataGridView1.DataSource = e.Result;
        dataGridView1.Update();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        b.RunWorkerAsync();
    }
}

Schauen Sie sich an a Hintergrundbearbeiter. Ich weiß selbst nicht viel über sie, aber eine kleine Suche bei Google zeigt dies als gute Möglichkeit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top