调用程序“延迟”的最佳方法是什么?

时间:2009-02-25 21:58:36

标签: delphi

有两个程序,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。

3 个答案:

答案 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都不会立即发生,它们都需要等到消息循环被检查