Invalid cross thread access backgroundworker error c#

筅森魡賤 提交于 2019-12-25 17:45:20

问题


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Threading;

namespace SRS
{
    public partial class excelimport : Form
    {
        public excelimport()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openfiledialog1 = new OpenFileDialog();

            if (openfiledialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.textBox1.Text = openfiledialog1.FileName;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {

            if ( backgroundWorker1.IsBusy != true)
            {
                backgroundWorker1.RunWorkerAsync();
            }
        }

        DataTable mysource;
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            for (int i = 1; (i <= 10); i++)
            {
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                string pathconn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source= " + textBox1.Text + " ;Extended Properties=\"Excel 12.0 Xml;HDR=YES;\";";
            OleDbConnection conn = new OleDbConnection(pathconn);

            OleDbDataAdapter mydatapter = new OleDbDataAdapter("select * from [" + textBox2.Text + "$]", conn);
            DataTable dt = new DataTable();

            mydatapter.Fill(dt);
                    datagridview1.datasource=dt;
                    System.Threading.Thread.Sleep(500);
                    worker.ReportProgress((i * 10));
                }
            }


        }


        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.tbprogress.Text = (e.ProgressPercentage.ToString() + "%");
        }

        private delegate void tododelegate();

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if ((e.Cancelled == true))
            {
                this.tbprogress.Text = "Canceled!";
            }

            else if (!(e.Error == null))
            {
                this.tbprogress.Text = ("Error: " + e.Error.Message);
            }

            else
            {
                this.tbprogress.Text = "Done!";
            }
        }

        private void excelimport_Load(object sender, EventArgs e)
        {
        }


    }
}

I get the error message in line :

datagridview1.datasource=dt;

I tried to alter the code like this :

private DataTable loadingtable()
        {
            string pathconn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source= " + textBox1.Text + " ;Extended Properties=\"Excel 12.0 Xml;HDR=YES;\";";
            OleDbConnection conn = new OleDbConnection(pathconn);

            OleDbDataAdapter mydatapter = new OleDbDataAdapter("select * from [" + textBox2.Text + "$]", conn);
            DataTable dt = new DataTable();

            mydatapter.Fill(dt);

            return dt;
        }

and in load event dataGridView1.DataSource = mysource;

and in bw worker mysource =loadingtable();

and then there is no error but then load data takes forever.


回答1:


You can't update UI controls on a non-UI thread.

Try this:

datagridview1.Invoke(() => datagridview1.datasource = dt);



回答2:


You are modifying the GUI from your background worker (which is a no-no) when you do this: datagridview1.datasource=dt;

Have a look for examples that use InvokeRequired and Invoke to show how to get some code executed on the event dispatch thread for you.




回答3:


A BackgroundWorker allows you to run some piece of code in a separate thread from the UI, so you don't lock up the program. The caveat is that the code cannot touch the UI thread directly. You're trying to update a control from the separate thread, so you get an exception.

You've already subscribed to and are using the ProgressChanged event, so take advantage of it. It runs on the UI thread.

worker.ReportProgress(i * 10, dt);

...

private void backgroundWorker1_ProgressChanged(object sender,
                                               ProgressChangedEventArgs e)
{
    this.tbprogress.Text = (e.ProgressPercentage.ToString() + "%");

    dataGridView1.DataSource = (DataTable)e.UserState;
}

FYI, you're assigning the DataSource within a loop, so each iterate overwrites the previous DataSource. You probably want to double-check your logic.

Also, you've got syntax errors. It's DataSource, not datasource.



来源:https://stackoverflow.com/questions/28597958/invalid-cross-thread-access-backgroundworker-error-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!