Form.Invoke冻结了UI

时间:2011-11-11 09:40:28

标签: c# .net multithreading freeze

我一直在谷歌上搜索大约一个小时,我仍然没有找到任何解决方案。

我只是尝试从另一个线程设置进度条的最大值。所以我找到了Control.Invoke方法。我一直在努力实施它:

enter image description here

现在,当我调试我的应用程序时,它只是停留在this.Invoke行。用户界面出现了,它被冻结了。所以我继续前进并谷歌说出来,它告诉我使用this.BeginInvoke()。我实现了它,我很好,UI不冻结。 这很安静,但实际上我的进度条的最大值没有变化:(

我做错了什么?

编辑:也许这有帮助:我使用Parallel.Invoke();来管理我的线程......

5 个答案:

答案 0 :(得分:5)

Control.Invoke只会阻止在工作线程上调用它并阻止UI线程。

您发布的代码是正确的。你必须在其他地方阻止UI线程。

答案 1 :(得分:2)

我在我的应用程序中使用了类似的东西,我用它来更新进度条的实际值。我从你的例子中改了一下。给它一个旋转,看看它是否有帮助:)

    public void SetMax(int value)
    {
        if (this.ProgressBar_status.InvokeRequired)
        {
           this.BeginInvoke(new Action<int>(SetMax), value);
           return;
        }
        this.ProgressBar_status.Maximum = value;
    }

答案 2 :(得分:0)

我建议最好使用后台工作组件,它支持在进度条中报告进度,包括其他功能,而不是调用invoke和BeginInvoke。您可以在以下MSDN链接中找到有关后台工作人员的更多详细信息:

http://msdn.microsoft.com/en-us/library/c8dcext2.aspx

答案 3 :(得分:0)

我遇到了同样的问题,感谢Nicholas的回答,我意识到我在GUI应用程序中遇到了同样的陷阱来调试Windows服务中使用的类。服务类在线程中运行大部分代码。当线程停止时,该线程正在回调一个日志记录过程。我使用按钮停止它,并使用日志记录来更新文本框。问题是如此简单我踢了自己 - 调用正在等待按钮单击完成,这正在等待类停止等待调用以记录它正在停止(重复直到任务管理器结束进程)。通过在停止按钮中创建一个线程来解决,用threadproc来停止服务类。这意味着我必须在新线程的另一个调用中在停止之后添加更多代码来更新表单,但这样做没有问题,因为它没有等待主表单线程。

答案 4 :(得分:0)

在我的情况下,错误是在启动线程后使用 join()。 join()阻止主线程在子线程完成之前执行代码。 我删除了join()命令,并在join()之后将代码移动到线程,一切正常。