多线程 – 让Delphi TTimer与多线程应用程序配合使用

我有一个问题,一个简单的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;

当我在一个简单的项目/演示中执行代码时,Everthing工作正常,但在我的应用程序(使用Omni Thread Library v3)中,timer事件永远不会被触发

我很确定这没什么,我只是想不通是什么问题!

我检查了三次:我的代码中只分配了一次MyTimer,正确分配了OnTimer事件等等……

我正在使用Delphi 2010

谁知道如何解决这个问题?

最佳答案
TTimer是一个基于消息的计时器.创建TTimer的任何线程上下文必须具有活动消息循环,以便TTimer处理其WM_TIMER消息.

TTimer不是线程安全计时器.为了接收WM_TIMER消息,它必须为自己分配HWND窗口句柄.它使用VCL的AllocateHWnd()函数来实现,该函数不是线程安全的,不能从主线程的上下文之外调用.

如果你需要一个线程安全计时器,可以直接调用CreateWindow()并直接泵送/处理WM_TIMER消息,或者使用不同的计时器机制,例如通过timeSetEvent()的线程多媒体计时器,或者甚至只是一个简单的繁忙循环通过Sleep()或WaitForSingleObject().在不知道您使用计时器的情况下,很难确定适合您需求的替代方案.

转载注明原文:多线程 – 让Delphi TTimer与多线程应用程序配合使用 - 代码日志