有两个程序,A1和A2,它们都在代码中调用函数B:
function B: boolean;
begin
// do other stuff
end;
procedure A1;
begin
// do stuff
if b then
...
// do stuff
end;
procedure A2;
begin
// do stuff
if b then
A1; // <- how to call A1 "delayed"?
// do stuff
end;
如果A2中的条件为真,则必须调用过程A1,但是当A2仍在运行时会发生这种情况,这是我不想要的。
应该发生的事情是: 如果A2中的条件为真,那么A2应该结束,在离开A2之后,应该调用程序A1。
一个丑陋的解决方案是设置一个在确保A2完成的延迟后调用A1的计时器。
但必须有更好的方法,对吧?
编辑:在我的情况下,A1和A2是事件,因此它们不会被代码调用,我不能在A2完成后从调用过程中调用A1。
答案 0 :(得分:12)
鉴于你的约束,听起来你想在PostMessage
之前调用A2
作为最后一件事。应设置PostMessage
参数,以触发A1
事件。唯一要担心的是竞争条件,但我不确定这将是Windows消息队列的问题。
答案 1 :(得分:0)
您可以使用布尔标志:如果A2正在运行则设置“A1_should_run”,并检查A2末尾的标志。这个解决方案很简单,但很丑陋,因为它为代码添加了非局部性,并不适用于更复杂的情况。
您可以使用呼叫队列:A1和A2始终通过放置在队列上运行,在这种情况下,您只需将A1排队。这种解决方案并不像您的情况那么简单,但非常适用于更复杂的情况。
答案 2 :(得分:0)
我过去通过创建一个延迟的方法调用单元来处理类似的问题。如果你只是在一个地方需要它可能会有点过头但是它很有用。
就我而言,我会写
procedure A2;
begin
// do stuff
if b then
DelayedCall('A1' {identifier}, A1 {event}, 0 {ms delay}, [] {various function flags});
// do stuff
end;
内部DelayedCall将A1放置在有序列表上(按时间排序)。计时器轮询列表(以可变频率取决于第一个事件到期的时间)并运行任何到期事件。
这不是一个非常复杂的函数,但它可能非常有用。
编辑: 在提供的示例中,使用PostMessage可以更快地运行。在A2完成之后,DelayedCall才会运行(除非A2在那里有一个ProcessMessages或Sleep调用)但是在A2完成后它可能不会立即运行,具体取决于其他内容。但是我经常在类似的场景中使用DelayedCall。
PostMessage或DelayedCall都不会立即发生,它们都需要等到消息循环被检查