我可以在没有后台进程的情况下避免“不响应”消息吗

Posted

技术标签:

【中文标题】我可以在没有后台进程的情况下避免“不响应”消息吗【英文标题】:Can I Avoid "Not Responding" messages without a background process 【发布时间】:2017-04-05 08:41:10 【问题描述】:

我有一个专门的应用程序,它是计算密集型的,可在主窗体上的组件中偶尔提供可调整的视觉反馈。我的主窗体还有一个滑块,用于控制用户如何在计算速度和 UI 响应速度之间取得平衡。我知道如何创建后台工作线程,但这不是我的意图,因为允许 UI 线程连续处理消息会使我的计算速度降低几个数量级。我想故意阻止滑块控制的 UI 线程。经过一定数量的可调整循环后,我允许 UI 在我的代码中使用 Application.DoEvents() 指令处理消息,此时所有待处理的 UI 更新都会被处理。我允许循环由滑块控制。 UI 释放前 50 次循环提供了良好的视觉响应时间,没有明显的 UI 滞后,而 UI 释放前 2000 次循环在 UI 赶上之前大约需要 15 秒,但极大地提高了计算速度。

话虽如此,当滑块设置为阻止 UI 时,是否有任何方法可以避免发布模式程序从“无响应”到常规模式来回循环?

谢谢。

感谢您的所有回复。 谢谢你的建议。计算和表单上的几个 UI 组件之间有很多交互。我已经尝试过使用基于 Invoke 委托的模板的后台线程,该模板具有 Internet 上其他地方建议的扩展方法,并且按照您建议的方式工作,但是使计算变得如此缓慢以至于荒谬。作为一种解决方法,我可以将 component.visible 设置为 false,这样只会让进度条实时更新,这几乎可以像最大化我的滑块一样加快速度,但坦率地说,只看进度并不好玩bar 而不是每 10 秒左右在主视觉组件上看到更新。我正在推送很多像素,这就是我出于 IP 原因可以在此应用程序上提供的所有信息。所以我的问题仍然存在,我可以把我的蛋糕也吃掉吗?我可以关闭那些使我的应用程序表单闪烁的 Windows 消息吗?我有解决方法,但我都不喜欢,而且不直接解决问题的 cmets 对我没有用处。感谢您的耐心和理解。

【问题讨论】:

一个设计合理的 UI 消耗或多或少 0% 的 CPU,所以你的代码肯定有问题。那“视觉反馈”是什么?无论你在做什么,我敢打赌你在每次迭代中都会给出反馈——不要这样做。每秒只更新几次反馈,这就足够了。 “控制用户如何平衡计算速度和 UI 响应速度的滑块” 嗯?为什么有人必须在这些之间做出选择? 感谢您的关注。回答您的问题,因为设计合理且适销对路的应用程序不会在没有内置资源的情况下将程序员的决定强加给用户。除非你喜欢每周发布更新。 “允许 UI 线程持续处理消息会使我的计算速度降低几个数量级”表明您的 UI 代码存在严重问题。正确的设计是 UI 线程做 UI,后台线程做计算 - 不需要滑块 【参考方案1】:

您应该将任何繁重的计算实现为后台线程,并将进度/结果与 UI 同步。

采用这种方式,您将永远不会阻塞 UI,并且会在用户可以在 UI 上看到他们的进度时完成大量计算。

另外,请避免在非常小的时间间隔内显示 UI 上的进度。 1、2 甚至 5 秒的刷新可能就足够了!

我会看看其他问答:Invoke in Windows Forms。它很旧,但对您来说应该是一个好的开始。

【讨论】:

【参考方案2】:

自己找到了解决方案。感谢大家对您的专业知识的帮助。

我现在正在将所有像素写入到不可见的图像中。这允许计算引擎不受与 UI 交互的阻碍,以最大速度进行。每隔一段时间,我就会将图像的克隆分配给可见组件,它提供实时反馈,但不以牺牲计算速度为代价。

能够在 1000 处硬编码 UI 更新并摆脱滑块。 UI 更新每 3-5 秒发生一次。不错。

好多了。

【讨论】:

以上是关于我可以在没有后台进程的情况下避免“不响应”消息吗的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有超时/死锁的情况下在PROMELA进程中发送和接收?

我可以在没有通知权限的情况下使用 FCM 接收消息吗?

如何在没有错误消息或异常的情况下调试 PowerShell 进程

linux后台开发中避免僵尸进程的方法总结

RabbmitMQ-工作队列及相关概念

实施后台位置更新后,FCM 发疯并在没有编程触发的情况下连续发送