Delphi - timer inside thread generates AV

前端 未结 6 1979
忘掉有多难
忘掉有多难 2020-12-07 23:56

I have the following thread code which executes correct first time. After that from time to time I get an AV on the Execute method of the thread, e.g

6条回答
  •  死守一世寂寞
    2020-12-08 00:16

    TTimer is not thread-safe. Period. Don't even try to use it with a worker thread.

    You are instantiating the TTimer in the worker thread's constructor, which means that it being instantiated in the context of the thread that is creating the worker thread, not the context of the worker thread itself. That also means that the timer will run in that same thread context and the OnTimer event andler will not be triggered in the context of the worker thread (if at all), so the body of your OnTimer handler needs to be thread-safe.

    To have the TTimer.OnTimer event be triggered in the context of the worker thread, you have to instantiate the TTimer inside the thread's Execute() method instead. But that has another set of pitfalls. TTimer creates a hidden window using AllocateHWnd(), which is not thread-safe and cannot safely be used outside the context of the main thread. Also, TTimer requires the creating thread context to have an active message loop, which your thread does not.

    To do what you are attempting, you need to either switch to using the Win32 API SetTimer() function directly (which allows you to bypass the need for a window) and then add a message loop to your thread (which you still need whether you use a window or not), or else switch to a different timing mechanism. You could use a waitable timer via CreateWaitableTimer() and WaitForSingleObject(), i which case you don't need a window or a message loopp. Or you can use a multimedia timer via timeSetEvent() (just make sure your multimedia timer callback is thread-safe because the timer will run in its own thread).

提交回复
热议问题