Autor Beitrag
CHLINDE
Hält's aus hier
Beiträge: 5



BeitragVerfasst: Sa 25.04.09 09:28 
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.
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 26.04.09 18:44 
Ok, hat geklappt.
Hier sind die Codeauszüge:

ausblenden volle Höhe 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!