Entwickler-Ecke

Datenbanken (inkl. ADO.NET) - Per Backgroundworker Daten aus einer DB-Tabelle auslesen


CHLINDE - Sa 25.04.09 09:28
Titel: Per Backgroundworker Daten aus einer DB-Tabelle auslesen
Ich möchte aus einer Tabelle, die häufig sehr groß ist, Daten auslesen und in ein Datagrid schreiben.
Um nicht die gesamte Anwendung zu blockieren, führe ich diese Prozedur in der DoWork-Methode eines Backgroundworkers aus.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            OleDbCommand Befehl = new OleDbCommand();
            if (treeView_Tabellen.InvokeRequired)
            {
                treeView_Tabellen.Invoke(new MethodInvoker(DatenAuslesen));
                return;
            }

            Befehl.CommandText = "SELECT * FROM [" + this.treeView_Tabellen.SelectedNode.Text + "]";
            Befehl.Connection = DatenbankverbindungQuelle;
            OleDbDataAdapter DatenAdapter = new OleDbDataAdapter(Befehl);
            DataTable Tabelle = new DataTable();
            Tabelle.Locale = System.Globalization.CultureInfo.InvariantCulture;

            DatenAdapter.Fill(Tabelle);
            dataGridView_TabellenInhalt.DataSource = Tabelle;    
        }

Während dieser Backgroundworker die Daten ausliest, soll ein Progressbar im Marquee-Style permanent durchlaufen. Das klappt aber nicht; sowie der Backgroundworker-Prozess startet, verschwindet der Progressbar auf dem Formular.

Zum Test habe ich statt des Datenbankauslesens mal ein Thread.Sleep(3000) eingebaut, dann funktioniert das Ganze wie gewollt: Im Thread wird die 3 Sekunden gewartet, gleichzeitig fährt der Progressbar permanent weiter.


Kha - Sa 25.04.09 10:35

Da du dich nicht im GUI-Thread befindest, ist InvokeRequired immer true, dein BackgroundWorker macht also überhaupt nichts. Im DoWork-Eventhandler musst du die GUI-unabhängige Logik unterbringen, über das RunWorkerCompleted-Event kannst du dann das Ergebnis in der GUI präsentieren.


CHLINDE - So 26.04.09 18:44

Ok, hat geklappt.
Hier sind die Codeauszüge:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
        private void InitializeBackgroudWorker()
        {
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.WorkerSupportsCancellation = true;
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            Form_Fortschritt.Show();
            backgroundWorker1.RunWorkerAsync(this.treeView_Tabellen.SelectedNode.Text);
        }

        private DataTable DatenAuslesen(string sTabelle, BackgroundWorker worker, DoWorkEventArgs e)
        {
            DataTable Tabelle = new DataTable();

            if (worker.CancellationPending)
            {
                e.Cancel = true;
            }
            else
            {
                OleDbCommand Befehl = new OleDbCommand();

                Befehl.CommandText = "SELECT * FROM [" + sTabelle + "]";
                Befehl.Connection = DatenbankverbindungQuelle;
                OleDbDataAdapter DatenAdapter = new OleDbDataAdapter(Befehl);

                Tabelle.Locale = System.Globalization.CultureInfo.InvariantCulture;

                DatenAdapter.Fill(Tabelle);
            }
            return Tabelle;
        }

        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            e.Result = DatenAuslesen((string)e.Argument, worker, e);
        }

        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Form_Fortschritt.Hide();
            progressBar1.Style = ProgressBarStyle.Blocks;
            this.dataGridView_TabellenInhalt.DataSource = e.Result;
        }

Versuche jetzt noch auf dem Form_Fortschritt die Möglichkeit eines Abbrechen-Buttons zu implementieren. Denke aber, dass das nicht unbedingt so schwierig wird.

Vielen Dank!