在我们的软件中,我们遇到异步执行事件的问题。有时候,一个功能会闯入"另一个有各种怪异结果的人。
我在这里处理用户输入和触发事件的计时器。
问题在于,不是逐个执行与事件绑定的代码,而是在Delphi为其提供窗口的第一个可能时刻完成:application.processmessages。这给出了一些问题,即有时一半的函数A完成,然后函数B"中断",完成,之后,函数A的后半部分完成。这可以给人以惊喜"结果
有没有好办法解决这个问题?
我尝试的事情:
-
接下来,我正在考虑尝试构建某种"命令队列"我可以在那里收到我的活动并以十五种方式解雇他们。
除了重建我们从头开始的一切外,还有其他/更好的方法来解决这些问题吗?
答案 0 :(得分:4)
有没有好办法解决这个问题?
首先消除对ProcessMessages
的所有使用。正如您所发现的,当从那里调用时,它会搞砸定时器事件处理程序。在其他地方使用,它经常受到竞争条件的影响,可能隐藏真正的问题。 找出问题所在并解决问题。
但我们依赖于某些第三方组件,我发现这些组件也会触发应用程序.processmessages。
计时器事件处理程序应该只进行短时间的工作。如果您通过调用计时器事件处理程序内的第三方库来调用ProcessMessages
,请取消该调用。除了重写库或以其他方式调用库之外,没有其他方法可以解决。
除了重建我们从头开始的一切外,还有其他/更好的方法来解决这些问题吗?
通常,你也可以在线程中进行后台工作,提供不直接调用任何VCL RTL方法的规则。如果第三方组件正在调用ProcessMessages
,则无法执行此操作。
如果您无法更改第三方组件,则可以向表单发布消息,并将调用放入处理此消息的方法中。使用现代Delphi,您可以使用@MasonWheeler的DelayedAction。但我真的建议你选择" hard"方式并修复第三方lib。
答案 1 :(得分:4)
最好的方法是取消对Application.ProcessMessages
的调用。大多数情况下,还有其他方法可以做Application.ProcessMessages
应该做的事情。您需要仔细查看为什么需要该呼叫,然后找到更好的解决方案。例如,您不需要Application.ProcessMessages
来更新UI。还有其他方法可以做到这一点。
如果第三方组件正在呼叫Application.ProcessMessages
,那么请联系该供应商,他们应该用更合适的功能替换此呼叫。如果这不是一个选项,您可以尝试使用在线程中使用该组件的变通方法(如果可能)。或者创建一个不可见的模态窗口并在ShowModal函数中执行组件的方法。这至少会避免用户输入消息。 (“隐形模态窗口”是一个BorderStyle=bsNone
,大小= 1×1和100%透明度的表单。