使用control.begininvoke后,UI仍然没有响应

Ani*_*oel 2 c# begininvoke

我做了一个C#winforms应用程序.现在我有一个有很多按钮的表单,它调用了大量的数字运算函数,其输出我在文本框中更新.我调用textbox.begininvoke()方法,我将委托传递给更新文本框中文本的函数,但是当文本很大时,表单没有响应,因为我无法单击取消按钮.是不是有任何方式使整个表单保持响应,并且更新也不断发生.我必须向用户显示数据,因为它即将到来,我无法缓冲整个事情并最终显示.我还尝试实现自己的缓冲区并以特定的时间间隔显示数据,这对于少量文本很有用,但是大量的UI只是没有响应.任何帮助?谢谢

更新问题是因为出现了一些混淆

  • 我在一个单独的线程上调用了数字运算功能.
  • 只要数据到达以更新文本框,该数字运算函数就会调用control.begininvoke函数
  • 我的UI得到显示,我看到输出即将来临,但是当数据量巨大时,我无法做任何其他活动,尽管我仍然可以看到UI

Fre*_*örk 9

调用BeginInvoke(或Invoke)不会给你带来任何东西,除非数字运算函数在除UI线程之外的另一个线程上运行.

请考虑以下代码:

private void HardWork(object state)
{
    for (int i = 0; i < 10; i++)
    {
        Thread.Sleep(500);
        SetText(i.ToString());
    }
}

private void SetText(string text)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action<string>(SetText), text);
    }
    else
    {
        textBox1.Text = text;
    }
}
private void Button_Click(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem(HardWork);            
}
Run Code Online (Sandbox Code Playgroud)

Button_Click方法将HardWork在单独的线程上开始执行该方法.HardWork将进行一些处理(通过Thread.Sleep调用模拟),然后调用方法来显示一些进度.在这个方法中,我们需要检查我们是否在UI线程上.如果我们不是,我们使用Invoke(或BeginInvoke)调用相同的方法,以强制它在UI线程上执行.

更新:如果从数字运算方法发出的数据量非常大,这当然可能会对UI响应性产生负面影响.例如,如果您在线程方法中累积了大量文本并在每次更新时发出该文本,那么这将比发布自上次更新后发生的更改更慢.文本框也是如此; 仅使用新文本调用TextBox.AppendText将比重复分配TextBox.Text属性更快.

由于我们没有看到您的代码实际执行的操作,因此很难提供有关如何解决您的特定问题的更详细的想法.


Tor*_*mod 7

你倒退了.

您应该使用BeginInvoke来更新UI.它似乎不会产生一个新的线程,你似乎相信.

BeginInvoke只是"在最初创建控件的线程中执行以下操作",这是您的UI线程.

因此,您应该在数字运算线程中使用BeginInvoke将更新回发到UI中.

希望这可以帮助