I want to compile a Delphi 4 project in Delphi 6.
I'm getting a problem with the method 'synchronize' of TThread. The thread
I'm calling 'synchronize' from is not the main thread. After calling
synchronize nothing happens. Both threads (the main thread and the thread
I've called synchronize from) seem to hang.
Using the debugger I found that after executing the following line
WaitForSingleObject(SyncProc.Signal, INFINITE);
the program don't get back. Also the method I want to be executed by
synchronize is never called.
The application I compiled with Delphi 4 is working correct! Does anybody
know what I'm doing wrong? I running the program on Windows NT 4 with SP6a.
Thanks in advance
Matthias
--
Jeff Overcash (TeamB) I don't think there are any Russians
(Please do not email And there ain't no Yanks
me directly unless Just corporate criminals
asked. Thank You) Playing with tanks. (Michael Been)
> Using the debugger I found that after executing the following line
>
> WaitForSingleObject(SyncProc.Signal, INFINITE);
>
> the program don't get back.
Clearly SyncProc.Signal is never signalled. Without more information,
though, we can't say why that is so.
--
Ray Lischner, author of Delphi in a Nutshell
http://www.tempest-sw.com
Matthias,
as you have probably discovered by now the mechanism that implements
Synchronize has been completely reworked in D6. There are a number of
consequences that may not be immediately evident:
In the old mechanism a message was send to a window in the main thread. This
caused the main thread to wake up if it was blocked in the message loop or if
the main threads code called Application.ProcessMessages (which calls
PeekMessage).
In the new mechanism this is no longer the case. The processing of
synchronized calls is dependent on calls to Application.Idle now, and that
is only called when the application has just processed a message in the
standard message loop and finds no more messages in the queue. Idle is *not*
called when you call Application.ProcessMessages in code! This is a rather
problematic design IMO. If you run threads in a DLL the *DLLs*
Application.Idle will *never* be called, unless the DLL has a modal dialog up
or you build DLL and app with run-time packages.
There is a mechanism to get Synchronized calls to be processed if the main
thread is waiting in the message loop, the Classes WakeMainThread variable.
In fact TApplication already assigns a handler method to this variable in its
constructor. Unfortunately this does not solve the main problem. The handler
used (TApplication.WaitMainThread) is called in the context of the thread
that is originating the Synchronized call. It does a
PostMessage(Handle, WM_NULL, 0, 0);
and that will wake up the main thread sitting in a WaitMessage call. If it
does not sit there (e.g. it is in a processing loop that calls
ProcessMessages) the message will be processed without the intended effect:
calling Application.Idle afterwards.
So, if you are now using ProcessMessages: call the CheckSynchronize function
afterwards. If you are using threads in a DLL do not use Synchronize at all.
The same applies if you write console apps of course, unless you write your
own input processing loop that calls CheckSynchronize in the main thread.
Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitly requested!
Note: I'm unable to visit the newsgroups every day at the moment,
so be patient if you don't get a reply immediately.
thanks for your help. At the moment I think nothing what you wrote can be
the reason for my problem. My program is a normal EXE program. In the thread
many informations into an Interbase database and showing the progress of the
operation in a form of the main thread.
I wrote a short test application, which is working correct. Now I will try
bring up step by step my test program to what my problem application is
doing. So I hope I will find out which part of my program is the reason for
the problem.
Thanks to you!
Matthias