English 中文(简体)
Multithreaded (TThread) Delphi application will not terminate
原标题:

I have written an application (using Delphi 2009) that allows a user to select a series of queries which can be run across a number of different systems. In order to allow queries to be run concurrently, each query is run in its own thread, using a TADOQuery object. This all works fine.

The problem that I have is when I try to close the application when a query is still running (and therefore a separate thread is active). When I create each thread, I record the thread s THandle in an array. When I try to close the application, if any threads are still running, I retrieve the thread s handle and pass it to TerminateThread, which should theoretically terminate the thread and allow the application to close. However, this doesn t happen. The main form s onClose event is triggered and it looks like the application is closing, but the process remains active and my Delphi interface appears as though the application is still running (i.e. "Run" button greyed out, debug view active etc.). I don t get control back to Delphi until I manually end the process (either Ctrl-F2 in Delphi or via Task Manager).

I am using TerminateThread because the query can take a long time to run (a few minutes in cases where we re dealing with a million or so records, which in the end user environment is perfectly possible) and while it is running, unless I m mistaken, the thread won t be able to check the Terminated property and therefore won t be able to end itself if this were set to True until the query had returned, so I can t terminate the thread in the usual way (i.e. by checking the Terminated property). It may be the case that the user wants to exit the application while a large query is running, and in that case, I need the application to immediately end (i.e. all running threads immediately terminate) rather than forcing them to wait until all queries have finished running, so TerminateThread would be ideal but it isn t actually terminating the thread!

Can anyone help out here? Does anyone know why TerminateThread doesn t work properly? Can anyone suggest anything to get the threads running large ADO queries to immediately terminate?

最佳回答

You should be able to cancel an ADO Query by hooking the OnFetchProgress event, and setting the Eventstatus variable to esCancel. This should cause your query to terminate and allow the thread to close gracefully without having to resort to using TerminateThread.

问题回答

Instead of using threads with TADOQuery, maybe you should consider using the async options of ADO.

ADOQuery1.ExecuteOptions := [eoAsyncExecute, eoAsyncFetch, eoAsyncFetch];

Then when your application close, you can call :

ADOQuery1.cancel;

As you can read in the msdn using TerminateThread is dangerous.

TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination.

But it also is very effective in killing threads. Are you sure you are right in your conclusions? Maybe the thread is killed, but another thread is still running? Maybe your handles are not thread handles? Could you show us some code? Or even better: A small working example we could try for ourselves?





相关问题
determining the character set to use

my delphi 2009 app has a basic translation system that uses GNUGetText. i had used some win API calls to prepare the fonts. i thought it was working correctly until recently when someone from Malta ...

Help with strange Delphi 5 IDE problems

Ok, I m going nuts here. For the last (almost) four years, I ve been putting up with some extremely bad behavior from my Delphi 5 IDE. Problems include: Seemingly random errors in coride50.bpl ...

How to write a Remote DataModule to run on a linux server?

i would like to know if there are any solution to do this. Does anyone? The big picture: I want to access data over the web, using my delphi thin clients. But i´would like to keep my server/service ...

How convert string to integer in Oxygene

In Delphi, there is a function StrToInt() that converts a string to an integer value; there is also IntToStr(), which does the reverse. These functions doesn t appear to be part of Oxygene, and I can ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签