【问题标题】:C# Threading and upgrading GUIC# 线程和升级 GUI
【发布时间】:2015-01-07 01:59:46
【问题描述】:

我有这种情况:

表单“菜单”,您可以在其中单击“新建”,然后会出现一个插入表单(带有 showdialog)。如果您插入数据,我会在数据库上进行 INSERT 查询并关闭此表单。 在 showDialog() 语句之后,我有很多方法以顺序方式执行大量操作(非常重要),有时还会更新 dataGridView。 在所有这些计算之后,我模拟按下“新按钮”以允许用户插入新项目。 这是一个例子:

private void buttonNew_Click(object sender, EventArgs e)
{
        DialogResult dr = new DialogResult();
        InsertForm form = new InsertForm();
        dr = form.ShowDialog();

        if (dr == System.Windows.Forms.DialogResult.OK)
        {
            Method1();
            Method2();
            if (dataGrid2.RowCount > 0)
            {
               Method3();
               Method4();
               Method5();
               Method6();
               Method7();
               Method8();  
            }
            bNew.PerformClick();
        }
}

问题是“新”表单 (bNew.PerfomClick()) 会在 2-3 秒后出现,我等不及了。所以我尝试创建一个包含 Method1 到 Method8 的方法,在新线程中运行它并执行 bNew.PerfomClick(),但这不起作用,因为我的很多方法都更新了 datagridView。

有没有办法解决这个问题? 对不起我的英语不好。

------------更新------

现在我正在尝试这段代码:

    delegate string OperazioniDelegate();

    private string Operazioni()
    {
        if (!InvokeRequired)
        {
            Method1();
            Method2();
            ............
        }
        else
             Invoke(new OperazioniDelegate(Operazioni));
        return "";
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Operazioni();
    }

这样,新的插入表单会立即显示,但他的 UI 会被阻塞,直到 backgroundWorker 结束工作..

【问题讨论】:

标签: c# multithreading user-interface datagridview


【解决方案1】:

假设您在单独的线程中运行长时间运行的操作,该线程会更新 UI 元素(在您的情况下为 datagridview),则必然会遇到跨线程异常,因为后台线程运行的上下文与用户界面线程。使用 InvokeRequired,如下所示:

delegate void valueDelegate(string value);

    private void SetValue(string value)
    {   
        if (someControl.InvokeRequired)
        {
            someControl.Invoke(new valueDelegate(SetValue),value);
        }
        else
        {
            someControl.Text = value;
        }
    }

或使用 BackGroundWorker 类,它将自动编组从后台线程到 Ui 线程的调用。此链接中给出了后台工作人员的使用http://www.albahari.com/threading/part3.aspx#_BackgroundWorker

【讨论】:

  • 所以当他们需要更新 UI 时,我需要在单独的线程中执行方法,每个调用“valueDelegate”?
  • 是的,您需要在单独的线程中运行长时间运行的操作。但是每个都不需要调用所需的调用。此代码应该与 UI 代码一起存在,例如在 Form 类中。我更喜欢使用 BackGroundWorker,因为它会自动执行此封送处理,并且您还可以控制操作,例如获取操作进度或取消操作
  • 看起来您正在使用 Invoke required 和 BackgroundWorker 类。您应该使用其中任何一个。 BackgroundWorker 类为您提供了在后台启动操作的方法,当操作发生变化时,您可以直接更新 UI(不应使用 InvokeRequired)。此链接给出了使用 BackgroundWorker 的示例:stackoverflow.com/questions/16521680/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-30
相关资源
最近更新 更多