Thread, abort and wait - c#

I am aborting a thread (will be threads soon enough) and the problem is i need to stall until all threads have been aborted.
After doing the Thread.Abort(); I thought of using the Thread.Join() to wait until its been fully aborted. However that doesnt work. It just waits forever. How can i abort each thread and wait until its done before continuing?
Additional information: If your curious why - in this case I am closing a window, I pass a delegate func into the thread which it calls when its done (or aborted). If I dont stall then the window will close and the function will call invalid handles/objs. I can easily use the same method, stick a flag in and loop & sleep until all flags are set but that doesnt feel right.

I've learnt from many years experience with threads that there are a couple of rules that, if followed, make life a lot easier.
The one pertinent to this question is:
let threads control their own resources, including their lifetime.
I wouldn't abort a thread, I'd simply set up a communications method between the threads creator and the thread itself to signal the thread to terminate, and then let the thread itself shut down.
This method can often be as simple as a write-by-creator/read-by-thread flag which controls the threads main loop. If the thread has long running tasks while in the loop, you should also check periodically.
Then the creator thread should just join until the thread exits. Properly designed, you can set an upper limit to the time this will take.

Use a synchronisation object such as an Event. For example, each background thread has an Event associated with it. When the thread is terminating, it signals the Event. The main thread does a WaitHandle.WaitAll on the set of Events, and proceeds only when all Events are signalled.
Be warned that if there is a chance that the background threads will take a long time to terminate, blocking the main thread while waiting for them would create a bad user experience. So if this is the case, you may want to hide the window before blocking. Also, you'll want to test what the impact of this is on your callback delegate -- if the UI thread is blocked in a wait, will it be able to handle your delegate?
Might not a better design be not to call the delegate if the thread is being killed due to the window closing? Just have the main thread tell the background threads why they are terminating and have them skip the callback if the reason is "window closing." (This assumes that you are communicating with the threads, as Pax rightly recommends, rather than just calling Abort.)

Related

Why does Control.Invoke() calls PostMessage() instead of SendMessage()?

Control.Invoke() calls PostMessage() and then waits until the UI thread finishes processing the message. So why it does not calls SendMessage() instead (which by default waits until the UI thread finishes processing the message).
Control.Invoke() is a dangerous method, many .NET programmers have deadlocked their program with it. It should be very strongly avoided because of this. Simple everyday operations like closing a window become perilous. You'll want to wait until a worker thread cannot invoke anymore since nothing good happens when the thread keeps running but the UI is gone. So you signal the thread with, say, AutoResetEvent and wait for it to complete.
Such a wait is very likely to deadlock your program when the thread is calling Invoke() at just the wrong time. The thread cannot complete because it is stuck in the Invoke() call, the UI thread cannot service it since it is stuck in the wait. A "deadly embrace", neither thread can make progress and your program will hang. Quite hard to debug since it is not predictable and doesn't happen often enough, only goes wrong when the thread calls Invoke at exactly the same time.
Breaking that deadlock requires knowing that an Invoke() call is in progress so it can be cancelled. It is not knowable when you use SendMessage(). The lock on which it blocks is hidden in the OS. I've recently posted an answer about the problems with SendMessage, everything you read there applies here as well.
So Microsoft did not implement it that way and they use PostMessage. They add an entry to the invoke queue, call PostMessage to wake up the UI thread so it goes looking through that queue. And specific to Invoke over BeginInvoke, they block on a ManualResetEvent in the queue entry, signaled when the UI thread completed the call to the delegate target.
Now they can do something to avoid the deadlock, when a window closes it looks through the invoke queue and cancels any that had that window as the invoke target. Or in other words, the lock that's invisible when you use SendMessage and causes deadlock now becomes visible and can be released to break the deadlock.

Thread: How to re-start thread once completed?

I have a method void DoWork(object input) that takes roughly 5 seconds to complete. I have read that Thread is better suited than ThreadPool for these longer operations but I have encountered a problem.
I click a button which calls threadRun.Start(input) which runs and completes fine. I click the button again and receive the following exception:
Thread is running or terminated; it cannot restart.
Can you not "reuse" a Thread? Should I use ThreadPool? Why is Thread "better suited for longer operations" compared to ThreadPool? If you can't reuse a thread, why use it at all (i.e. what advantages does it offer)?
Can you not "reuse" a Thread?
You can. But you have to code the thread not to terminate but to instead wait for more work. That's what a thread pool does.
Should I use ThreadPool?
If you want to re-use a thread, yes.
Why is Thread "better suited for longer operations" compared to ThreadPool?
Imagine a thread pool that is serving a large number of quick operations. You don't want to have too many threads, because the computer can only do so many things at a time. Each long operation you make the thread pool do ties up a thread from the pool. So the pool either has to have lots of extra threads or may run short of threads. Neither leads to an efficient thread pool design.
For longer operations, the overhead of creating and destroying a thread is very small in comparison to the cost of the operation. So the normal downside of using a thread just for the operation doesn't apply.
If you can't reuse a thread, why use it at all (i.e. what advantages does it offer)?
I'm assuming you mean using a thread dedicated to a job that then terminates over using a thread pool. The advantage is that the number of threads will always equal the number of jobs this way. This means you have to create a thread every time you start a job and destroy a thread every time you finish one, but you never have extra threads nor do you ever run short on threads. (This can be a good thing with I/O bound threads but can be a bad thing if most threads are CPU bound most of the time.)
Thread.Start documentation says:
Once the thread terminates, it cannot be restarted with another call
to Start.
Threads are not reusable. I have already faced this problem a while ago, the solution was to create a new Thread instance whenever needed.
It looks like this by by design.
I encountered the same problem and the only solution I could find was to recreate the thread. In my case I wasn't restarting the thread very often so I didn't look any further.
A search now has turned up this thread on social.msdn where the accepted answer states:
a stopped or aborted thread cannot be stated again.
The MSDN repeat this as well:
trying to restart an aborted thread by calling Start on a thread that has terminated throws a ThreadStateException.
As the message states, you cannot restart the thread. You can simply create a new thread for your next operation. Or, you might consider a design where the background thread keeps working until it completes all of your tasks, rather than launch a new thread for each one.
for(;;){} or while(true){} are useful constructs to 'reuse' a thread. Typically, the thread waits on some synchronization object at the top of these loops. In your example, you could wait on an event or semaphore and signal it from your button OnClick() handler.
It's just in background mode. It sounds like you need to use the ThreadPool because re-starting and re-creating Thread objects are very expensive operations. If you have a long running job that may last longer than your main process, then consider the use of a Windows Service.

C# Communication between threads

I am using .NET 3.5 and am trying to wrap my head around a problem (not being a supreme threading expert bear with me).
I have a windows service which has a very intensive process that is always running, I have put this process onto a separate thread so that the main thread of my service can handle operational tasks - i.e., service audit cycles, handling configuration changes, etc, etc.
I'm starting the thread via the typical ThreadStart to a method which kicks the process off - call it workerthread.
On this workerthread I am sending data to another server, as is expected the server reboots every now and again and connection is lost and I need to re-establish the connection (I am notified by the lost of connection via an event). From here I do my reconnect logic and I am back in and running, however what I easily started to notice to happen was that I was creating this worker thread over and over again each time (not what I want).
Now I could kill the workerthread when I lose the connection and start a new one but this seems like a waste of resources.
What I really want to do, is marshal the call (i.e., my thread start method) back to the thread that is still in memory although not doing anything.
Please post any examples or docs you have that would be of use.
Thanks.
You should avoid killing the worker thread. When you forcibly kill a Win32 thread, not all of its resources are fully recovered. I believe the reserved virtual address space (or is it the root page?) for the thread stack is not recovered when a Win32 thread is killed. It may not be much, but in a long-running server service process, it will add up over time and eventually bring down your service.
If the thread is allowed to exit its threadproc to terminate normally, all the resources are recovered.
If the background thread will be running continuously (not sleeping), you could just use a global boolean flag to communicate state between the main thread and the background thread. As long as the background thread checks this global flag periodically. If the flag is set, the thread can shut itself down cleanly and exit. No need for locking semantics if the main thread is the only writer and the background thread only reads the flag value.
When the background thread loses the connection to the server that it's sending data to, why doesn't it perform the reconnect on its own? It's not clear to me why the main thread needs to tear down the background thread to start another.
You can use the Singleton pattern. In your case, make the connection a static object. Both threads can access the object, which means construct it and use it.
The main thread could construct it whenever required, and the worker thread access it whenever it is available.
Call the method using ThreadPool.QueueUserWorkItem instead. This method grabs a thread from the thread pool and kicks off a method. It appears to be ideal for the task of starting a method on another thread.
Also, when you say "typical ThreadStart" do you mean you're creating and starting a new Thread with a ThreadStart parameter, or you're creating a ThreadStart and calling Invoke on it?
Have you considered a BackgroundWorker?
From what I understand, you just have a single thread that's doing work, unless the need arises where you have to cancel it's processing.
I would kill (but end gracefully if possible) the worker thread anyway. Everything gets garbage-collected, and you can start from scratch.
How often does this server reboot happen? If it happens often enough for resources to be a problem, it's probably happening too often.
The BackgroundWorker is a bit slower than using plain threads, but it has the option of supporting the CancelAsync method.
Basically, BackgroundWorker is a wrapper around a worker thread with some extra options and events.
The CancelAsync method only works when WorkerSupportsCancellation is set.
When CancelAsync is called, CancellationPending is set.
The worker thread should periodically check CancellationPending to see if needs to quit prematurely.
--jeroen

Best Way to wake a thread up to quit? C#

I spawn a thread (only one) to do some work and it pretty much takes care of itself not accessing any data outside of the tread except calling callback() to see if the user wants to quit (also sends a status report back to the main thread to display in the GUI).
When the close closes the exe i would like to wake up the thread and have it quit, whats the best way of doing this? The callback already says if the user wants to quit so now the issue is using Thread.Sleep and waking it up prematurely so it can quit instead of having the process live for another few seconds or minutes. This feature would be nice for stop to exit more quickly.
Another approach would be as follows:
Have a ManualResetEvent in your program and call Set when you want the thread to finish up and close down. Instead of calling Thread.Sleep on your work thread, call event.WaitOne and pass in a TimeSpan object. If the event is signalled, your worker thread will wake up before the timeout occurs - WaitOne will return true.
Use a BackgroundWorker or set your thread's IsBackground property to true, then it won't keep your application open.
I'd recommend the BackgroundWorker, but the latter is a quick fix.
Update
Original poster changed his requirements after posting the question (see comments attached to this question). Update to answer follows:
If you want to stop a background operation without ending the application, please see Background worker's CancelAsync method. Also, don't use Thread.Sleep - use a WaitHandle and call WaitOne on what you need to wait for.
I have to agree with Mark. The only thing clear about your question is that you need to reexamine your threading strategy.
You say you have a thread doing work but then you say you want to wake it up?
Is the thread waiting for work? If so, sleep in shorter cycles and check for exit more often or use a reset event. The best way to wake a thread up is to not put it to sleep. Do what you have to do and exit. Always check for interrupt signals, in whatever form you implement them, before starting any long running operations, and again, if you must sleep the thread, do it in short cycles.
Is the thread busy and you want to interrupt it? You may have no choice but to kill it if you cannot instrument it such that it can respond to interrupt signals in a timely fashion.

AutoResetEvent and COM Objects

I've noticed that AutoResetEvent completely freezes the message loop (sometimes) when in the middle of a WaitOne() call, effectively even blocking the signal message.
IE:
(UI) New thread spawned
(UI) Code calls WaitOne(); timeout: 10s
(T2) Thread opens device, calls Set()
(UI) WaitOne blocks message loop
(UI) WaitOne timeout elapsed, code execution continues
(UI) Main window receives signal and continues (but WaitOne failed)
Any ideas?
EDIT: added UI/T2's to specify threads. Also, I'm trying to turn a 3rd party library to synchronous. Opening devices involves an Open() call that in turn spawns an OpenOK or OpenFailed event, I'm trying to make a bool Open() call that returns true/false depending on which event was spawned.
... effectively even blocking the signal message.
You can't "block a signal" from being sent, you can only prevent the other thread from getting to the point of setting the event. Wait handles do not require a message pump at all.
The only thing I can think of may be that the COM object in question is tied to the UI thread. Accessing the COM object may be attempting to invoke back from T2 to the UI thread which is waiting for T2 to do something (deadlock). To see if this is indeed the problem make sure you are not creating or accessing the COM object on the UI thread.
This is the result of a race condition. The problem is that step 3 might be happening before step 2 because they're on different threads. Because you're using an AutoResetEvent, by the time WaitOne is called, the event is already reset.
Because of this problem, whenever possible, I generally try to avoid AutoResetEvents in favor of ManualResetEvents.
The order of events with a ManualResetEvent would be (I've listed event 2 as 2a and 2b to demonstrate that their order of operation is not guaranteed):
New Thread Spawned
a. Original thread calls WaitOne(); b. New thread calls Set();
Original thread wakes up.
Original thread calls Reset();
You might find this SO post on "Waiting on the mainthread while continuing to process"
Also checkout Calling Synchronous Methods Asynchronously from MSDN

Categories