问题描述
我遇到了一个简单的TTimer问题,该问题已启动并在主应用程序线程中执行了其OnTimer事件,代码如下:
I have an issue with a simple TTimer that's initiated and have its OnTimer event executed in the main app thread, the code looks like this:
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)中,计时器事件从不触发
Everthing work just fine when I execute the code in a simple project/demo, but in my app (which uses Omni Thread Library v3), the timer event is never fired
我很确定没事,我只是想不出什么毛病!
I'm pretty sure it's nothing, I just can't figure out what's wrong!
我三遍检查:MyTimer
在我的代码中仅分配了一次,其OnTimer事件已正确分配,等等...
I triple checked: MyTimer
is only assigned once in my code, its OnTimer event is correctly assigned, etc...
我正在使用Delphi 2010
I'm using Delphi 2010
有人知道如何解决这个问题吗?
Anyone knows how to fix this?
推荐答案
TTimer
是基于消息的计时器.在创建TTimer
的任何线程上下文中,都必须具有活动的消息循环,以便TTimer
处理其WM_TIMER
消息.
TTimer
is a message based timer. Whatever thread context the TTimer
is created in must have an active message loop in order for TTimer
to process its WM_TIMER
messages.
TTimer
不是线程安全的计时器.为了接收WM_TIMER
消息,它必须为其分配一个HWND
窗口句柄.这样做是使用VCL的AllocateHWnd()
函数实现的,该函数不是线程安全的,因此不能从主线程的上下文之外调用.
TTimer
is not a thread-safe timer. In order to receive the WM_TIMER
messages, it has to allocate an HWND
window handle for itself. It does so using the VCL's AllocateHWnd()
function, which is not thread-safe and must not be called from outside the context of the main thread.
如果您需要线程安全的计时器,请直接调用CreateWindow()
并直接泵送/处理WM_TIMER
消息,或者使用其他计时器机制,例如通过timeSetEvent()
的多线程多媒体计时器,甚至只是通过Sleep()
或WaitForSingleObject()
的简单繁忙循环.不知道您将计时器用于什么用途,很难找到适合您需求的替代品.
If you need a thread-safe timer, either call CreateWindow()
directly and pump/process the WM_TIMER
messages directly, or else use a different timer mechanism, such as a threaded multimedia timer via timeSetEvent()
, or even just a simple busy loop via Sleep()
or WaitForSingleObject()
. Without knowing what you are using the timer for, it is difficult to pin-point an alternative that suits your needs.
这篇关于使Delphi TTimer与多线程应用程序一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!