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

2024-03-02

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

由于出现一些混乱而更新问题

  • 我在一个单独的线程上调用了数字运算函数。
  • 每当数据到达时,该数字处理函数就会调用 control.begininvoke 函数来更新文本框
  • 我的用户界面开始显示,我看到输出,但是当数据很大时,我无法执行任何其他活动,尽管我仍然可以看到用户界面

调用 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);            
}

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

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

很难就如何解决您的特定问题提供更详细的想法,因为我们还没有看到您的代码实际做了什么。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 control.begininvoke 后 UI 仍然没有响应 的相关文章

随机推荐