c# - 使用 control.begininvoke 后 UI 仍然无响应

标签 c# begininvoke

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

在出现一些混淆时更新问题

  • 我在单独的线程上调用了数字运算函数。
  • 每当数据到达以更新文本框时,数字运算函数就会调用 control.begininvoke 函数
  • 我的 UI 开始显示,我看到了输出,但是当数据很大时,我无法进行任何其他事件,尽管我仍然可以看到 UI

最佳答案

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

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

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

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

关于c# - 使用 control.begininvoke 后 UI 仍然无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/881202/

相关文章:

c# - 表单已经关闭时调用时出错

c# - InvokeRequired 和 BeginInvoke 等效项

c# - C# 中并发异步读取单个文件中多个位置的推荐方法

c# - VS2017 无法发现 MSTest 测试

c# - 调用和开始调用

c# - BeginInvoke、EndInvoke 的多线程问题?

c# - 将多个参数传递给 BeginInvoke()

c# - 定义要使用 dotnet watch 运行的命令

c# - 如何将 VB.net 常量转换为 C#?

c# - 在不定义模型类的情况下查询ravendb?