为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
红颜莎娜 2022-11-13 13:36:17
我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?
查看完整描述

2 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

这是您需要做的:


    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 

            }

        }

    }




查看完整回答
反对 回复 2022-11-13
?
慕妹3146593

TA贡献1820条经验 获得超9个赞

我不确定这是否是一个好的解决方案,但这可行。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;

}


查看完整回答
反对 回复 2022-11-13
  • 2 回答
  • 0 关注
  • 87 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信