繁体   English   中英

Form.Invoke冻结UI

[英]Form.Invoke freezes the UI

我已经搜寻了大约一个小时,但仍然找不到任何解决方案。

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

在此输入图像描述

现在,当我调试我的应用程序时,它只是停留在this.Invoke行上。 UI出现,并且被冻结。 因此,我要继续进行搜索并将其搜索出来,它告诉我使用this.BeginInvoke() 我实现了它,很好,UI不会冻结。 不错,但是实际上我的进度条的最大值没有改变:(

我究竟做错了什么?

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

仅在工作线程上调用Control.Invoke且UI线程被阻止时, Control.Invoke才会阻止。

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

我在应用程序中使用下面类似的内容,用于更新进度条的实际值。 我已经从您的示例中对其进行了一些更改。 旋转一下,看看是否有帮助:)

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

我遇到了同样的问题,由于尼古拉斯的回答,我意识到自己陷入了一个GUI应用程序中的同一个陷阱,以调试Windows服务中使用的类。 服务类在线程中运行大多数代码。 线程停止时正在回调记录程序。 我使用按钮停止它,并且日志记录使用了调用来更新文本框。 这个问题是如此简单,我踢了自己-调用正在等待按钮单击完成,它正在等待类停止,而该类正在等待调用记录以使其停止(重复执行,直到任务管理器结束过程为止)。 通过在停止按钮中单击创建线程来解决,使用threadproc来停止服务类。 这意味着我不得不在停止之后在新线程的另一次调用中放置更多代码来更新表单,但是这样做没问题,因为它没有等待主表单线程。

就我而言,错误是在启动线程后使用join() join()防止主线程在子线程完成之前执行代码。 我删除了join()命令,并在join()之后将代码移至线程,一切正常。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM