I have a class that inherits System.ComponentModel.Component. The component spawns a bacground thread that makes a long blocking call that waits for outside event. In my Dispose the thread is signaled to finish its call and return. Can I be sure that app will always call my Dispose? How can I ensure that my thread does not linger and prevent client app from terminating?
How can I ensure that my thread does not linger and prevent client app from terminating?
Make the thread a background thread via Thread.IsBackground. This will keep the thread from keeping the process alive.
There is no way to guarantee that IDisposable.Dispose will be called on your object. You can expect finalizer to be called in all normal cases.
As Dispose is only convention, not requirement you have to enforce it through good coding practice and potentially run time checks in finalizer (if you want).
The good way of not blocking the app is not to make long synchronous calls. Most APIs have asynchronous versions that are much easier to cancel/ignore completion part. If you can't - use Thread.IsBackground as Reed Copsey suggested.
Related
My scenario:
a few BackgroundWorkers to perform various functions.
one of them, and only once, will have to execute to do a special work first before continue and letting other works to do their job.
I'm using Monitor.TryEnter: do this special work when it's true (locking is successful); when it's false, will wait for the lock to be released.
Problem is that this special work is done asynchronously. I have a listener, and the CompletedSpecialWork method will be called, but the Thread is different from the Thread where Monitor.TryEnter was performed (that is, the Thread holding(locking) the object). I need a way to be able to send a message to the original Thread asking to release the object.
I tried to have a static object of SynchronizationContext, but when I do threadHoldingLock = SynchronizationContext.Current it is null (it is being called from the BackgroundWorker that was able to hold the lock).
My question is: from this CompletedSpecialWork context/thread, how can I send a request to the original thread (holding the lock) to release the lock via Monitor.Exit? I need like a way to send a Invoke to the original thread with Monitor.Exit on it.
Try using either ManualResetEvent or AutoResetEvent.
These can be used to block one thread and then (via function call from a running thread into the blocked thread) allow the block to be reset.
They are syntactic sugar on top of a Semaphore but I like the simplified interface.
Good luck!
By their very nature synchronization objects like mutexes need to be released from the same thread that acquired a lock on them. It would pretty much make any kind of synchronization a crashy hit&miss affair if this requirement didn't exist and all your threads could just randomly release all locks from all threads.
You should look at Event objects to signal simple pulses between threads.
I have a long running Task that internally blocks on Monitor.Wait with no timeout. My class has a Dispose method that allows it to unblock and then wait for that task to complete. However, in some usages my clients won't call Dispose at all, which causes the Task remain blocked forever.
Will this be an issue?
How can I signal that task when the client application is shutting down?
I'm thinking about using of a Finalize method, but it seems error prone to me.
EDIT:
I have found a nice article explaining a lot of such things in just few pages:
http://www.albahari.info/threading/threading.pdf
You got into this pickle by abusing Dispose(). Client code is not likely to use it when it is shutting down, there's just no point in disposing unmanaged resources early when the finalizer runs a millisecond later anyway.
But it is not an issue. A long running Task uses a thread that has its IsBackground property set to true. Which saves your bacon, the CLR will automatically terminate the thread when it shuts down. There is no scenario where that blocked Task can prevent the program from ending normally.
You need to perform a Monitor.PulseAll(Object) using the instance of the object upon your Monitor.Wait(Object) is holding.
From MSDN:
Monitor.PulseAll
Notifies all waiting threads of a change in the object's state.
The solutions are
ensure that you carefully manage the lifetime of objects that use Monitor methods
Thread.Abort. Absolutely horrible idea but no doubt someone will mention it. It will get the job done by it may leave things in a mess.
before you call Monitor.Wait, register the object parameter with a static field that you can use to PulseAll at any period. I can't recommend this as good design but it is a nice bandaid fix.
So I am thinking of an instance of a class where I want a thread to run for the life of the class, but terminate when the process that invoked the class is no longer running. This is not the case of a parent thread terminating a child, but a single spinning (in a wait loop perhaps) thread exiting gracefully without holding resources etc.
I think that in C++, you can tell the thread to terminate using a volatile bool from the destructor, however in C# the ~ is not a destructor it is a finalizer. I have not been able to successfully terminate a thread using the finalizer. Perhaps I am missing something there. I know that it is better practice is to have all threads die a natural death without signaling its termination, but it is just not efficient to be spawning a thread each time I need to do something. Yes I know about thread pools, but I think it would be better to have a single listener thread respond to calls to the class, and have it gracefully die when the class is put on the gc.
The real trick is, I think, can I know, or how do I know when the class that is running the thread is first placed on the gc. Is IDisposable what I am looking for? I am not using any unmanaged code here.
I think you basically have two sensible choices.
Choice One:
If you really don't have any unmanaged resources in use, then you can just let the system close your thread when the program closes. This is obviously the simplest solution.
You only have to worry if you are using objects which have dispose methods that should be called. That includes open files, but probably wouldn't include something like a font.
If you do this, you must ensure that the thread will be running as a "background" thread. The only difference between a background thread and a foreground thread is that when the program closes, all background threads will be automatically terminated - but foreground threads won't.
If you use a Task, by default it will be run as a background thread.
You definitely won't want to do this if your thread will be doing some IO to disk or doing anything else that mustn't be interrupted.
Choice Two:
Add a thread cancellation mechanism, using CancellationTokenSource and arrange to use it at program shutdown, and wait for the thread to exit.
In this case you won't really care whether the thread is foreground or background because you will be managing the program shutdown yourself, and the thread will be stopped properly before the program exits.
If you take this route, you can encapsulate the thread cancellation logic and other thread handling methods in a class that wraps the thread. Then you can add a Dispose() method so you can create the class inside a using block to ensure proper shutdown even in the face of exceptions.
I have taken this approach quite often, and it seems to work quite nicely.
I found a decent looking example of how to call a delegate asynchronously with a timeout... http://www.eggheadcafe.com/tutorials/aspnet/847c94bf-4b8d-4a66-9ae5-5b61f049019f/basics-make-any-method-c.aspx. In summary it uses WaitOne with a timeout to determine if the call does not return before the timeout expires.
I also know that you should have an EndInvoke to match each BeginInvoke.
So what happens if the wait timeout expires? We (presumably) DON'T want to call EndInvoke as that will block. The code can go on to do 'other things', but have we leaked anything? Is there some poor thread someplace blocked waiting for a return that's never going to happen? Have we leaked some memory where the result-that-will-never-return was going to be placed?
I think this post talks about it very well:
From the post:
You can't terminate an executing async delegate if it's not your thread, but you can if it is. If you use the common BeginInvoke type methods, you get a thread pool thread managed by the framework. If you use the Thread() class you get you own thread to manage, start, suspend, etc. as you like.
Developing asychronously requires that one decide who will manage the threads. The many different methods that execute asynchronously are using the ThreadPool threads behind the scenes.
Since you can't/shouldn't terminate a thread pool thread then you must design you code to communicate with the thread so that it can exit. The MSDN examples for the BackgroundWorker component demonstrates this kind of communication.
Sometimes your code may have the thread blocking waiting for IO. Here you would normally use a multiple object wait instead, waiting for IO or for a ManualResetEvent.
So in short, youll need to find a way to manage the threads yourself if there is a possibility of timing out and you want the thread to end.
You need to call EndInvoke().
Here is a link talking about what happens with EndInvoke():
Is EndInvoke() optional, sort-of optional, or definitely not optional?
Here is a link to the article in the accepted answer.
We had all been talking about the 'fire and forget' technique with asynchronous delegate invocation in various public forums. Many DevelopMentor instructors had written articles and example code showing the technique, and we had all described it in class. And of course it was in Don's book by then too. So when Microsoft eventually remembered to let the outside world know that this technique is not in fact legal, it was rather astonishing.
An MSDN link on the asynchronous pattern.
You will leak the resources held by the thread. There will be various bits of .NET remoting plumbing objects like the AsyncResult. Several unmanaged handles associated with the thread. All peanuts compared to the one megabyte of virtual memory address space you'll leak, held by the thread stack.
You cannot abort the thread in any way, the leak is permanent. When you have to deal with badly behaving code like this, your only good resource is to run it in a separate process so you can get Windows to clean up the shrapnel when you shoot the process in the head with Process.Kill(). Even that is not guaranteed, these kind of freezes tend to be associated with misbehaving device drivers. Process.Kill won't terminate a device driver thread. Easy to see: trying to abort the process with Taskmgr.exe will leave it running with one Handle. You have some hope if that doesn't happen.
What is the difference between Thraed.Abort() and Thread.Interrupt(). How can I call them in a Thread Safe Manner.It would be helpful,if simple example is provided.
First of all, neither of these are good thread synchronization constructs.
First, Thread.Abort says "I don't care what you're doing, just stop doing it, and leave everything as it is right now". It's basically the programming way of saying "Hey, beat it". If your thread is having files open, those files will be left open until garbage collection gets around to finalizing your objects.
Thread.Abort should only ever be used, and even then probably not, in the case when the app domain that the thread is running inside is being torn down, preferably only when the process is being terminated.
Secondly, Thread.Interrupt is a rather strange beast. It basically says "I don't care what you're waiting for, stop waiting for it". The strange thing here is that if the thread isn't currently waiting for anything, it's instead "I don't care what you're going to wait for next, but when you do, stop waiting for it immediately".
Both of these are signs that you're imposing your will on a thread that wasn't designed to be told such things.
To abort a thread properly, the thread should periodically check some kind of flag, be it a simple volatile Boolean variable, or an event object. If the flag says "You should now terminate", the thread should terminate itself by returning from the methods in an orderly fashion.
To properly wake a thread, a thread should, in places where it has to wait for synchronization objects, include a "please stop waiting" object that it also waits on. So basically it would for either the object it needs becomes signaled, or the "please stop waiting" object becomes signaled, determine which one that did, and do the right thing.
So instead of Thread.Abort and Thread.Interrupt, you should write your threads using normal synchronization objects, like events, mutexes, semaphores, etc.
For the same reason, Thread.Suspend and Thread.Resume should be left alone, and they have also been obsoleted in the later versions of .NET.
Unless you're calling Abort or Interrupt on the currently executing thread (as ASP.NET does to terminate a request abruptly, for example) you basically can't call them in a thread-safe manner.
Use a WaitHandle or Monitor.Wait/Pulse to wait in a wakeable way. You should only abort other threads if you're tearing down the application, basically - as otherwise you can end up in an unknown state.
See my article on graceful thread termination for an example of how to do this nicely.
Thread.Abort() raises a ThreadAbortException on the target thread. It's intent to generally to force the thread to terminate. It is not a recommended practice for stopping a thread's processing.
Thread.Interrupt() interrupts a thread that is in WaitSleepJoin state - essentially blocking on a resource like a WaitHandle. This allows the caller to unblock the thread.
Neither is really "thread-safe" - in the sense that they are specifically intended to affect the behavior of threads in a way that is hard to predict.
It's generally recommended to use synchronization objects (like WaitHandles or Semaphores) to allows threads to safely synchronize with one another.
The difference between Abort and Interrupt is that while they will both throw an exception (ThreadAbortException and ThreadInterruptException), calling Abort will rethrow the exception at the end of the catch block and will make sure to end your running thread.