Abort a thread?
I want to implement interruptable tasks based on background threads. What is the cleanest way to implement the TTask.Stop
method? How can I abort the background thread?
The code executed within the thread context is passed to the task using an anonymous method and can contain blocking calls, so I can开发者_JS百科't rely on the fact, that the Terminated
flag is checked regularly from within the code.
Thanks for any input.
Using D2010 in case it matters (some things in TThread
seem to have changed)
There is no way to safely abort a running thread. This is true for Windows programs whether written in Delphi or not, and whether using Delphi 2010 or earlier. It's an OS limitation if you want to call it that, but actually it's a limitation of threading, as aborting a thread without making sure it is not holding locks or something like that will wreak havoc with your program.
What you can do is to call the TerminateThread()
API function, which is evil. Read the list of problems and warnings in this link and see whether you still want to call it. There is no other way that works without cooperation from the task code.
Isolate the job into a separate process. Depending on how you communicate with the background job, this is probably the best way of guaranteeing that you can abort it cleanly.
For example, it's probably not a good ide to use shared memory for communication; use files or pipes, or a similar mechanism that doesn't break or stall when the other end gets killed. If you use named mutexes for cross-process synchronization, be aware that there is a particular error state for these synchronization primitives: WAIT_ABANDONED is returned by WaitForSingleObject and friends if a thread (or, implicitly, process's main thread) which last held the primitive was terminated without cleanly releasing it. Basically, this means you need to use a staged transactional approach to data transfer, so that you can ignore possibly inconsistent state that was being modified at the time of the termination.
精彩评论