猿问

使用 BackgroundWorker 从 UI 获取信息,然后更新 UI

我DataGridView通过运行 SQL 查询来填充BackgroundWorker. 如果我直接在按钮事件处理程序中运行代码,我的代码将完美运行,但是当我放入DoWorkBackgroundWorker 时,它不会更新 UI。我的代码如下。


DataTable tab1table = new DataTable();


public Form1()

{

    InitializeComponent();

    Instantiatesearch1Thread();

}


private void Instantiatesearch1Thread()

{

    search1Thread.WorkerReportsProgress = true;

    search1Thread.WorkerSupportsCancellation = true;

    search1Thread.ProgressChanged += search1Thread_ProgressChanged;

    search1Thread.DoWork += search1Thread_Dowrk;

    search1Thread.RunWorkerCompleted += search1Thread_RunWorkerCompleted;

}


    private void sbutton1_Click(object sender, EventArgs e)

{

    search1Thread.RunWorkerAsync();

}

void search1Thread_Dowrk(object sender, DoWorkEventArgs e)

{

    int percentprogress = 0;

    percentprogress++;

    Thread.Sleep(1000);

    // Search1 button event handler

    using (SqlConnection conn = new SqlConnection(connectionstring))

    {


        conn.Open();

        using (SqlDataAdapter cmd = new SqlDataAdapter(comboBox1SQL, conn))

        {

            if (comboBox1.Text.Contains("ID"))

            {

                long para = long.Parse(search1.Text);

                cmd.SelectCommand.Parameters.Add(new SqlParameter

                {

                    ParameterName = "@combo1Par",

                    Value = para,

                    SqlDbType = SqlDbType.BigInt

                });

            }


通过使用 aMessageBox我发现代码没有访问if comboBox1.Text.Contains()语句,我认为这是有道理的,因为该信息来自 UI 并且BackgroundWorker不能直接访问 UI。这也可以解释为什么当时tab1datatable并tab1table没有受到影响。


我想我需要在Invoke某处使用该方法,但我不确定如何使用。我查看了c# - 在执行期间将信息从 UI 传递给 BackgroundWorker,但它并没有真正回答我的问题。如果Invoke是我需要的,我如何在此代码中实现以允许它从 UI 获取信息并随后用填充的更新它DataGridView?


红颜莎娜
浏览 88回答 2
2回答

慕尼黑5688855

这是您需要做的:    private string search1_Text = "";    private string comboBox1_Text = "";    private void Instantiatesearch1Thread()    {        search1_Text = search1.Text;        comboBox1_Text = comboBox1.Text;        search1Thread.WorkerReportsProgress = true;        search1Thread.WorkerSupportsCancellation = true;        search1Thread.ProgressChanged += search1Thread_ProgressChanged;        search1Thread.DoWork += search1Thread_Dowrk;        search1Thread.RunWorkerCompleted += search1Thread_RunWorkerCompleted;    }在运行后台工作程序之前,您基本上获取了所需数据的副本。然后您只需访问DoWork代码中的字段:    void search1Thread_Dowrk(object sender, DoWorkEventArgs e)    {        int percentprogress = 0;        percentprogress++;        Thread.Sleep(1000);        // Search1 button event handler        using (SqlConnection conn = new SqlConnection(connectionstring))        {            conn.Open();            using (SqlDataAdapter cmd = new SqlDataAdapter(comboBox1SQL, conn))            {                if (comboBox1_Text.Contains("ID"))                {                    long para = long.Parse(search1_Text);                    cmd.SelectCommand.Parameters.Add(new SqlParameter                    {                        ParameterName = "@combo1Par",                        Value = para,                        SqlDbType = SqlDbType.BigInt                    });                }                else if (comboBox1_Text.Contains("Other Thing") || comboBox1_Text.Contains("Other Stuff"))                {                    string para = search1_Text;                    cmd.SelectCommand.Parameters.Add(new SqlParameter                    {                        ParameterName = "@combo1Par",                        Value = "%" + para + "%",                        SqlDbType = SqlDbType.NVarChar,                    });                }                // Clear datatable if it contains any information and then fill it                // tab1datatable is a DataGridView                if (tab1table != null)                    tab1table.Clear();                cmd.Fill(tab1table);                //tab1datatable.DataSource = tab1table;                // A bunch of expensive calculations             }        }    }

慕妹3146593

我不确定这是否是一个好的解决方案,但这可行。CheckForIllegalCrossThreadCalls初始化时设置为 false BackgroundWorker。private void Instantiatesearch1Thread(){    // Initialize other stuff    CheckForIllegalCrossThreadCalls = false;}并在任务完成后将其设置为 false。private void search1Thread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){    // Do your work,    CheckForIllegalCrossThreadCalls = true;}
随时随地看视频慕课网APP
我要回答