c#线程到线程异常,在第二个窗体上使用Progressbar时将数据加载到datagridview

时间:2019-04-10 00:02:04

标签: c# datagridview

我正在将数据表中的数据加载到应用程序的datagridview中。 这样做时,我想通过第二个窗体通知用户该应用程序仍在运行,该窗体上有一个进度条显示其进度和一个Label,其中包含有关已向数据网格中装入多少行的信息。

我确实知道将数据加载到App中会冻结我的GUI,所以我决定使用第二种形式从我的主要任务中调用它。

我打电话

Task task = new Task(LeftJoinTables);
task.Start();

然后在LeftJoinTables中运行此代码

...
foreach(DataRow rows in FileJoinMail.Rows)
            {
                wfrm.UpdateProgressBar(++i);
                dataGridView1.Rows.Add(
                    false, //Checkbox
                    rows["Fullpath"],
                    rows["Filename"],
                    rows["File Size"],
                    rows["UserID"],
                    rows["E-Mail"],
                    rows["Date"]);
                wfrm.ProcInfo($@"Loading Data [{i.ToString()}/{count.ToString()}]");

            }

在第二个表单类上,我获得了此方法,该方法调用Waitform,Waitform使用信息更新Progressbar和标签

public void ProcInfo(string message)
    {
        this.Invoke((MethodInvoker)delegate
        {
            ProcInfoLabel.Text = message;
        });
    }

public void UpdateProgressBar(int value)
    {
        this.Invoke((MethodInvoker)delegate
        {
            ProcBar.Value = value;
        });
    }

但是从这一点来看,我遇到了线程冲突。.我以为使用invoke可以解决这个问题。

1 个答案:

答案 0 :(得分:1)

基本上,Windows UI(及其中的控件)使用消息泵(队列)更新,并且要使其正常工作,应创建控件的句柄。确保这一点的一种简单方法是确保您的表单可见(并且由于它是进度条,因此应该可见)。

    private void button1_Click(object sender, EventArgs e)
    {
        wfrm.Show(); // make sure you are making the form visible before updating
        Task task = new Task(LeftJoinTables);
        task.Start();
    }
    private void LeftJoinTables()
    {
        wfrm.ProcInfo("test");
    }

此外,您更新数据网格的调用也需要调用。

如果要在不显示控件的情况下强制其创建,可以使用以下内容(取自https://blogs.msdn.microsoft.com/mapo/2011/04/27/forcing-handle-creation-in-a-net-windows-forms-control/):

if (!mycontrol.IsHandleCreated)
   {
       // This call forces creation of the control's handle.
       IntPtr handle = mycontrol.Handle;
   }

类似的问题: Form.Invoke() does not run when form is hidden,