|
-
Aug 26th, 2013, 04:21 AM
#1
Thread Starter
Hyperactive Member
[RESOLVED] Best way to stop a thread ASAP
Hi folks,
I have an application which creates threads to do some real-world work.
If I want to make the real-world work stop/be cancelled obv I would like the thread to stop ASAP so that problems are not caused when the user connects or disconnects things from the system being controlled.
What is the best way to do this?
I know the use of thread.abort() is discouraged unless implemented with all the proper considerations. So I did take a look at what some of these considerations may mean for my code and things started to get a bit complex, but I am not averse to retying this if there is no neater way.
The work the threads are doing is not cyclical, they do the their work once then finish, so having some kind of cancellation flag that is polled as part of a loop is not relevant.
I just started looking at cancellation tokens, but I they look like they require polling as well
My threads are started as in this code:
VB Code:
Dim jobThread As New Thread(AddressOf DoJob) jobThread.Start(schedule.Item(keys(index)))
And the thread work itself looks something like the following psuedo-code:
VB Code:
Private Sub DoJob(ByVal job As Object) ' Get the related context object using the key in the job argument ' Run the context object's .NextStep method ' This involves reading from a DB and opening, reading from, ' writing to and closing a TCP connection and getting and setting ' members from other threads. SyncLock(threadCollectionLock) ' Remove the reference to this thread from my thread collection End SyncLock End Sub
Thanks, w
Thanks 
-
Aug 26th, 2013, 05:07 AM
#2
Re: Best way to stop a thread ASAP
I've just started using this - the Task Parallelism class - using a TaskFactory to create Tasks...
http://msdn.microsoft.com/en-us/library/dd537609.aspx
It's only for later versions of the framework - I think 4.0 and later...
Seems to be setup to support things like thread cancellation and what not.
-
Aug 26th, 2013, 05:58 AM
#3
Thread Starter
Hyperactive Member
Re: Best way to stop a thread ASAP
That looks quite interesting
I think Tasks use the ThreadPool however, which means there is a limit on the number of possible tasks. I thought this was 25, but now Im reading that may have changed?
Also, cancellation of tasks still requires that a token be polled.... This is my major issue - I dont (think) I want to be cooperative when I cancel the threads in this case. I just want them to immediately notice that I've asked them to stop, run some cleanup code, then stop and notify that they've stopped.
The problem with this however is the complexity of ensuring the cleanup code does whats necessary... e.g. if execution is within a SyncLock section and this type of cancellation happens, how can I release the lock? and so on.
Thanks 
-
Aug 26th, 2013, 06:01 AM
#4
Re: Best way to stop a thread ASAP
These are all just layers on top of the windows api. How would you immediately kill a running task with the windows api? Have you looked into that? Maybe once you have that you can better find a library/class to manage threads in that fashion.
-
Aug 26th, 2013, 06:25 AM
#5
Re: Best way to stop a thread ASAP
The internet is full of info saying that you cannot do what you want to do. Thread.Abort is not guaranteed to happen immediately.
What are you doing in the thread that cannot check a value every so often?? Some kind of Sleep getting in the way?
-
Aug 26th, 2013, 06:51 AM
#6
Thread Starter
Hyperactive Member
Re: Best way to stop a thread ASAP
WEll... I guess I can check, just not iteratively. It also means that a lot more of the actual work doe needs to be inside the actual DoWork function instead of being abstracted, else I cant poll as often. EG:
VB Code:
Sub DoWork()
' Get context object
' Poll for cancellation
' Call context object method to do the bulk of the work - this may take some time but does not poll for cancellation.
' Poll for cancellation
' Code to finish thread normally.
End Sub
Vs
VB Code:
Sub DoWork()
' Get context object
' Poll for cancellation
' Query DB
' Poll for cancellation
' Construct TCP message from query result
' Poll for cancellation
' Open TCP connection
' Poll for cancellation
' Send TCP data
' Poll for cancellation
' Wait for any reply
' Poll for cancellation
' If there is a reply, perform any actions that requires
' Poll for cancellation
' Save results to object properties
' Poll for cancellation
' Update progress in UI
' Poll for cancellation
' Code to finish thread normally.
End Sub
In the first one the code of DoWork() is less complex, the actions concerning the object are encapsulated within that object (its method) BUT the method represents a long period where polling does not occur.
In the second one polling occurs more often but you can see this leads to more complexity and the objects actions are now intermingled with the thread handling...
Maybe I should be passing the cancellation indicator/token onto the object's method and continue to poll within it?
Even so it still results in needing to "manually" poll every few instructions... and then their is a question of how often I should poll, every other line? or by some other less arbitrary decider? Obviously this depends very much on the actions being taken, e.g. I may wish my TCP connection to have a long timeout property, but I would also like it to be cut short as the thread is cancelled...
Thanks 
-
Aug 26th, 2013, 07:55 AM
#7
Re: Best way to stop a thread ASAP
Can you make an "operation" array that you can loop along - and in that loop SELECT/CASE off to each of these steps - so in fact you are looping but looping an "operation series" that you setup.
I tend to architect a lot of my multi-threaded stuff in this fashion - allows me to drop out at any step to return to UI (or send to client if it's a back-end service) and then comes back in and proceed from the step left from...
Might allow you to refactor all of this into a common thread-stepping-looping with "variable" operations placed inline.
Just a thought...
-
Aug 26th, 2013, 08:44 AM
#8
Re: Best way to stop a thread ASAP
I wouldn't say Abort() is discouraged but should not really ever be used unless "the world is crumbling beneath my feet situation". I am still confused why you can't set some flag. Thread killing should generally be left to the OS. Abort is not safe and this behavior is intentional. You will have absolutely no way of knowing where the thread is, you could be holding on the locked resources that need disposing, corrupt data & locked files are just a few examples. You should/could implement a worker method that supports cancellation and calling the cancel. Then your thread can choose a safe place to shut itself down safely.
-
Aug 26th, 2013, 09:47 AM
#9
Re: Best way to stop a thread ASAP
I'm afraid that you have no choice except to use the non-iterative polling you describe. There are clearly times in your code when an abrupt stop must not be allowed to happen, and other times when the thread may not even respond (if it is blocking on a call). Since your code breaks up into a series of discrete steps, you can probably find the key steps before which you can poll for termination. You can ignore polling for things that take virtually no time, so you will only be polling before the major, uninterruptable, steps of the process. Therefore, your first idea in #6 is probably too little, while your second idea is probably too much, though not by much. For instance, there really isn't a need to poll prior to querying the DB, since a SELECT query will be pretty harmless even if it doesn't need to happen. Therefore, in the odd case where you decide to terminate while the thread is getting the context, there really is nothing to be gained by terminating until after the DB query has returned. There may be and advantage to polling between the TCP connect and the Write, but you probably can't benefit from terminating between the write and the read on the TCP, so let the read happen before checking. If the read is blocking, this could be a significant chunk of time for the thread, but since you can't interrupt the read in progress, you will be waiting until it returns anyways.
Also, don't worry too much about the thread pool. The number of active threads is virtually certain to be far less than the pool capacity (which should be flexible, anyways, since a queued thread isn't doing anything). The OS is going to determine how many threads are active, and it will generally be roughly the same number as you have cores in your CPU. This figure is increased if threads spend a lot of time blocking on a call, and can be diminished if the active threads all end up starving for time. You have no control on that, nor do you want it. The algorithms that the OS uses are pretty well optimized, and you are unlikely to do better on your own.
My usual boring signature: Nothing
 
-
Aug 26th, 2013, 12:38 PM
#10
Thread Starter
Hyperactive Member
Re: Best way to stop a thread ASAP
Thanks for all the input folks!
I think I will spend more time looking at the TaskFactory and switch to if I dont find any other obstacles
Thanks 
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|