Question

If an user provides information that is recorded in an excel file then I choose Excel COM to read the data. However, as the user can repeat the process to N files and the process can take a while, I decided to move this routines to a separated thread.

Therefore, I need your advice to define how can I do this.

The worker thread cannot be destroyed until there is no more remaining files. Inside the thread the data is loaded to a ClientDataSet and at the end is applied to database.

I need somehow notify the user when task is done, so he can decide if he will load another file and execute the thread again or finish the job.

How to properly destroy the thread and notify the user?

Was it helpful?

Solution

Should I create and destroy the thread to each file?

You can, but that is not a very efficient design. Put the files into a thread-safe queue, then start the thread if it is not already running, and then have the thread loop through the queue util it is empty. At that time, the thread can then be destroyed, or just put to sleep in case more files will be queued later on.

This design also allows you to process multiple files in parallel if you implement a thread pool. When you put a file into the queue, start a new thread if there is not already an idle thread waiting to be used. When a thread starts, pull the next available file from the queue. When that thread finishes, it can pull the next file from the queue, and if there is no file then go back into the pool for later reuse.

If so, How to properly destroy the thread and notify the user?

When you are ready to destroy a thread, call its Terminate() method (its Execute() needs to should check its Terminated property periodically and exit when set to true), then call its WaitFor() method (or equivalent, like MsgWaitForMultipleOjects(), which allows you to keep the message queue responsive while waiting for the thread to terminate), then free it from memory. The thread triggers its OnTerminate event after Execute() exits, however it is not safe to destroy the thread in the OnTerminate event handler. If you want to destroy the thread when the OnTerminate event is triggered (especially if you are not expecting the thread to terminate, such as if it threw an uncaught exception), you can post yourself an asynchronous notification, such as with PostMessage(), PostThreadMessage(), TThread.Queue(), etc, and then destroy the thread when that notification is processed at a later time.

How to set a thread to notify the user when the work is finished? By assigning the event OnTerminate?

Yes. Unless the thread is going to process multiple files before terminating, in which case the thread could manually send a notification in between each file.

It's better to create the thread to each file or create 1 thread and somehow control it's execution to every time for different files?

Creating and destroying a thread is not trivial for the OS, in terms of resources and processing, so you should re-use threads as much as possible. Make them sleep when they have nothing to do, unless they are going to be sleeping for a long time in which case you should destroy them to release their resources.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top