本文介绍了使Delphi TTimer与多线程应用程序一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个简单的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与多线程应用程序一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 13:23