使用 Delphi 消息队列来避免重复触发昂贵的操作
using Delphi message queue to avoid repeatedly triggering expensive operations
在相对较重的表格上玩主从时,我惊喜地发现在滚动过程中详细信息部分没有立即刷新。
相反,只有当我停止大量滚动时才会触发刷新。
这与在 After-Scroll 事件中以编程方式执行 SetRange 相反,后者显然在每次滚动时都会被触发。
为简单起见,我们可以假设 'custom_operation' 是一个 SetRange,尽管它不必限于此,也可以是任何其他操作。
我一直在思考这在内部如何工作,我想到了 Delphi 消息队列:
我似乎无法找到描述队列优先级的文章,但它描述了队列中的消息如何根据其类型(硬件触发器、计时器、postmessage...,忘记确切顺序)具有不同的优先级。
会不会是 master-detail 内部通过发布消息请求设置范围来使用消息队列,但随后意识到发生了更多的滚动事件,因此删除了旧的 'custom' 消息并重新发布了新的消息一?这样,只有当没有更多的硬件消息时,才会处理 'custom' 消息。
能够延迟 custom_operation 直到用户停止做某事会很有用。
如何实现这一目标?谢谢!
是的,我知道。线程也可用于使用户体验更流畅,但首先避免 custom_operation 将节省不必要的网络流量。
我会使用 TTimer。我将从滚动事件处理程序重新启动(停止然后启动)计时器。如果事件来得不够快,定时器会在你操作的地方调用他的OnTimer事件处理器。
我在从 TEdit 派生的 TDelayedEdit 组件中完成了该操作。计时器从 OnChange 事件重新启动。如果用户继续打字,计时器永远不会结束,但是一旦用户停止打字的时间与计时器间隔一样长,则计时器会触发他的 OnTimer 事件,而我的组件会触发他的 OnChange 事件。
在相对较重的表格上玩主从时,我惊喜地发现在滚动过程中详细信息部分没有立即刷新。
相反,只有当我停止大量滚动时才会触发刷新。
这与在 After-Scroll 事件中以编程方式执行 SetRange 相反,后者显然在每次滚动时都会被触发。
为简单起见,我们可以假设 'custom_operation' 是一个 SetRange,尽管它不必限于此,也可以是任何其他操作。
我一直在思考这在内部如何工作,我想到了 Delphi 消息队列:
我似乎无法找到描述队列优先级的文章,但它描述了队列中的消息如何根据其类型(硬件触发器、计时器、postmessage...,忘记确切顺序)具有不同的优先级。
会不会是 master-detail 内部通过发布消息请求设置范围来使用消息队列,但随后意识到发生了更多的滚动事件,因此删除了旧的 'custom' 消息并重新发布了新的消息一?这样,只有当没有更多的硬件消息时,才会处理 'custom' 消息。
能够延迟 custom_operation 直到用户停止做某事会很有用。
如何实现这一目标?谢谢!
是的,我知道。线程也可用于使用户体验更流畅,但首先避免 custom_operation 将节省不必要的网络流量。
我会使用 TTimer。我将从滚动事件处理程序重新启动(停止然后启动)计时器。如果事件来得不够快,定时器会在你操作的地方调用他的OnTimer事件处理器。
我在从 TEdit 派生的 TDelayedEdit 组件中完成了该操作。计时器从 OnChange 事件重新启动。如果用户继续打字,计时器永远不会结束,但是一旦用户停止打字的时间与计时器间隔一样长,则计时器会触发他的 OnTimer 事件,而我的组件会触发他的 OnChange 事件。