我遇到一个问题,一个简单的TTimer,已启动并且在主应用程序线程中执行了OnTimer事件,代码如下所示:
procedure TForm1.DoSomeStuff();
begin
OmniLock.Acquire;
try
Parallel.Pipeline.NumTasks(MaxThreads).Stage(StageProc).Run;
if (MyTimer = nil) then
begin
MyTimer := TTimer.Create(nil);
MyTimer.Interval := 60 * 1000; // timer fired every 60 seconds
MyTimer.OnTimer := MyTimerEvent;
MyTimer.Enabled := True;
end;
finally
OmniLock.Release;
end; // try/finally
end;
当我在一个简单的项目/演示中执行代码时,工作正常,但在我的应用程序(使用Omni Thread Library v3)中,计时器事件从未被解雇
我很确定它什么都不是,我只是想不出来是什么问题!
我进行了三重检查:MyTimer
仅在我的代码中分配一次,其OnTimer事件正确分配等等...
我正在使用Delphi 2010
任何人都知道如何解决这个问题?
答案 0 :(得分:7)
TTimer
是基于消息的计时器。无论创建TTimer
的线程上下文是什么,都必须有一个活动的消息循环,以便TTimer
处理其WM_TIMER
消息。
TTimer
不是线程安全计时器。为了接收WM_TIMER
消息,它必须为自己分配HWND
窗口句柄。它使用VCL的AllocateHWnd()
函数,它不是线程安全的,不能从主线程的上下文之外调用。
如果您需要线程安全计时器,请直接调用CreateWindow()
并直接泵送/处理WM_TIMER
消息,或者使用不同的计时器机制,例如通过{{的线程多媒体计时器1}},甚至只是通过timeSetEvent()
或Sleep()
的简单忙碌循环。在不知道您使用计时器的情况下,很难确定适合您需求的替代方案。