Reputation: 717
I seem to have the challenge that a worker thread knows to close the application, but neither PostQuitMessage()
nor Application.Terminate()
seem to work. The Application just doesn't quit, no errors.
Do I have to set a flag to call one of these from the main thread, or is there another trick?
The thread checks for an updated version and calls an updater to replace the .exe
(once it's not locked anymore). After calling the updater, it needs to quit the application.
Upvotes: 1
Views: 459
Reputation: 2293
Remy has a great answer.
If you are using The Delphi Threads (your threads derive from TThread) then you can use the Synchronize method of your thread to run a routine in the context of the main thread, and then in that routine (which is run by the main thread) you can call Application.Terminate
See: http://docwiki.embarcadero.com/Libraries/Sydney/en/System.Classes.TThread.Synchronize
Upvotes: 0
Reputation: 595782
PostQuitMessage()
posts a WM_QUIT
message to the message queue of the calling thread. Application.Terminate()
uses PostQuitMessage()
. That is why neither is working in your case, since you are calling them in the wrong thread context.
So, you can either:
flag the main thread to call PostQuitMessage()
/Application.Terminate()
at its earliest conventience, such as with TThread.Queue()
:
TThread.Queue(nil, Application.Terminate);
post your own WM_QUIT
message to the main thread or Application
window, ie:
PostThreadMessage(MainThreadID, WM_QUIT, 0, 0);
PostMessage(Application.Handle, WM_QUIT, 0, 0);
post a WM_CLOSE
message to your MainForm
window (if you have one) 1, as closing the MainForm
will terminate the Application, ie:
PostMessage(Application.MainForm.Handle, WM_CLOSE, 0, 0);
1: just be careful with this one! The TWinControl.Handle
property is not thread-safe. If you read the MainForm's Handle
property in a worker thread while the main thread is in the process of (re-)creating the window, bad things can happen!
Upvotes: 5