MSDN on migrating legacy multithreaded applications (from this page on exception handling in threads):
In general, the change will expose previously unrecognized programming problems so that they can be fixed. In some cases, however, programmers might have taken advantage of the runtime backstop, for example to terminate threads. Depending on the situation, they should consider one of the following migration strategies:
Restructure the code so the thread exits gracefully when a signal is received.
Use the Thread.Abort method to abort the thread.
If a thread must to be stopped so that process termination can proceed, make the thread a background thread so that it is automatically terminated on process exit.
In all cases, the strategy should follow the design guidelines for exceptions. See Design Guidelines for Exceptions.
This suggests that using Thread.Abort is an appropriate way to terminate a thread. Has something changed while I wasn't looking? The last I'd heard was this could cause unexpected behaviours so shouldn't be used.
Thread.Abort is a lot safer than it used to be for the following reasons.
The runtime will defer aborts while execution is in unmanaged code.
The abort will allow finally blocks to execute.
However, there is still a problem with exactly when the ThreadAbortException gets injected. Consider this code.
public class Example
{
private DateTime value = DateTime.MinValue;
public void DoSomething()
{
try
{
value = DateTime.UtcNow;
}
finally
{
}
}
}
If this code were running on a 32-bit platform the value variable could be corrupted if Thread.Abort was called and the ThreadAbortException were injected in the middle of the write to value. Since DateTime is 8 bytes the write has to take place using more than one instruction.
It is possible to guard against this by placing critical code in a finally block and by using Constrained Execution Regions, but it would be incredibly difficult to get right for all but the simplest types your define. And even then you cannot just put everything in a finally block.
Generally speaking, Thread.Abort will kill threads, leaving the data they were processing at the time in an unknown state. The state being unknown, it's usually not safe to deal with that data anymore. However, when you're trying to terminate a process, you are not expecting to deal with that thread's data anymore, so why not abort it?
Well, the problem with Thread.Abort() is that will abort the thread possibly in the middle of work. That might cause your state to be corrupted. That's why is advisable to use a volatile bool flag to control the thread, and let the thread finish its task gracefully, but based on that flag.
For more details, I recall this blog post.
Related
Why would the following structure cause an AbandonedMutexException. Even if there is an error or method returns. The mutex is being released.
static Mutex WriteMutex = new Mutex(false, #"Global\mutex2203");
public static void Demo()
{
try
{
WriteMutex.WaitOne();
//rest of coding stuff here
}
finally
{
WriteMutex.ReleaseMutex();
}
}
Receives reports cant regenerate the bug.
Edit: The exception occurs at WriteMutex.WaitOne(); no other code. And only this method touches that mutex.
An AbandonedMutexException is thrown when one thread acquires a Mutex object that another thread has abandoned by exiting without releasing it (see AbandonedMutexException). The code you cite in your question would not necessarily be the code that is causing the exception, only "receiving" it (i.e. detecting the situation that throws the exception).
That is, code in another thread (could be the same method but is likely not) acquires the Mutex but does not release it and permits its thread to exit without the Mutex ever being released. Then the thread running the code you show above throws the exception when it attempts to acquire the Mutex.
Where is the exception occurring? Does it happen when you do WriteMutex.WaitOne();?
If so, there must be something (presumably not in the code you posted) that takes ownership of it, then exits happening before you get the exception.
Using async methods could also be a problem with code using Mutexes due to swapping the threads around. Make sure you aren't using any of that stuff in a non-compatible way.
Also, be aware that named mutexts are not local to your application: other processes could be screwing with it (and the problem could be there). If you want something local, don't give it a name, or even better use something more efficient and less error prone like the lock keyword for such cases.
Some nice details about using Mutex properly (and avoiding issues like you seem to have) are here: What is a good pattern for using a Global Mutex in C#?
You must also call WriteMutex.Dispose() in the finally block, but it is better to use a using block.
Try to use this pattern:
https://stackoverflow.com/a/229567/2185689
For me, I was getting "The wait completed due to an abandoned mutex." warning because the console app was running under the Task Scheduler and the task scheduler was terminating it. That was not behavior I wanted.
I resolved it by going to the task in question, Editing the Trigger and and unchecking the "Stop task if it runs longer than:" option.
Note that there are other options that can cause the task to termination as well.
Conditions Tab : Power -> "Stop if the computer switches to battery power"
Settings Tab : "Stop the task if it runs longer than:"
I would like to check whether following code is resistant against ThreadAbortException and will not lead into orphan lock. If it is not, what is the best pattern to avoid orphan locks here?
ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
public void DoStaff()
{
_lock.EnterWriteLock();
//Is this place where ThreadAbotException can corrupt my code, or is there JIT optimalization which prevent this from happening???
try
{
...
}
finally
{
_lock.ExitWriteLock();
}
}
According following link http://chabster.blogspot.cz/2013/07/a-story-of-orphaned-readerwriterlockslim.html, there is (or at least there was) possible way how to create orphan locks but I was running sample code for a while without any luck.
I am using .NET 4.0
Is there any difference between behavior in Debug and Release?
Yes, ThreadAbortException could occur there, in which case the try wouldn't be entered and therefore you would never exit the write lock.
There's no good general solution to the problem. Which is why Eric Lippert (among others) says that Locks and exceptions do not mix.
You're asking specifically about ThreadAbortException, which leads me to believe that you're contemplating using Thread.Abort for some kind of threading control in your application. I urge you to reconsider. If you want the ability to cancel your threads, you should use Cancellation or something similar. Using Thread.Abort in any other than the most dire circumstances is a horrifically bad idea. It certainly should not be part of your program's overall design.
In order for code which uses a locking primitive to be robust in the face of thread aborts, it is necessary that every lock-acquisition and lock-release request pass, or be performed through, an unshared token which can be given "ownership" the lock. Depending upon the design of the locking API, the token may be an object of some specific type, an arbitrary Object, or a variable passed as a ref parameter. It's imperative, however, that the token be created and stored by some means before the lock is acquired, so that if the token gets created but the store fails, the token may be abandoned without difficulty. Unfortunately, although monitor locks have added (in .NET 4.0) overloads of Monitor.Enter and Monitor.TryEnter which use ref bool as a token, I know of no equivalent for reader-writer locks.
If one wants abort-safe reader-writer lock functionality, I would suggest one would need a class which was designed around that; it should keep track of what threads hold reader or writer access and, rather than relying upon threads to release locks, it should, when waiting for a lock to be released, make sure the thread holding it is still alive. If a thread dies while holding read access, it should be released. If a thread dies while holding right access, any pending or future attempts to acquire the lock should throw an immediate exception.
Otherwise, there are some tricks via which a block of code can be protected against Thread.Abort(). Unfortunately, I don't know any clean way to bracket the code around a lock-acquisition request in such a way that Abort will work when the request itself can be cleanly aborted without having succeeded, but will be deferred if the request succeeds.
There are ways via which a framework could safely allow a thread which is in an endless loop to be killed by another thread, but designing mechanisms which could be used safely would require more effort than was put into Thread.Abort().
I'm working on improving the exception-safety of a piece of code and I realized that a raised ThreadAbortException may cause undesired resource leaks, even when guarding resources with the C# using construct. For instance, consider the following code (which could be running in a separate thread).
using (TextWriter writer = CreateWriter(filename))
{
// do something with the writer.
}
TextWriter CreateWriter(string filename)
{
return new CustomWriter(File.OpenWrite(filename));
}
If the thread running this code is abnormally terminated, then I would like the file handle referenced by filename to be closed immediately. Can I do this without replacing the use of the using construct with a try/finally block?
My assumption is that ThreadAbortException may be raised at anytime, which means I should pay attention to what is happening between statements. While I can guard against the exception in CreateWriter with a try/finally block, the using construct won't do the same until after the expression in the parenthesis is evaluated, meaning the file resource is left open if the exception occurs immediately after CreateWriter returns.
I understand that a finalizer will ultimately release the file handle, but I am wondering if there is a deterministic way to address this issue without catching ThreadAbortException in each place that CreateWriter is used.
Yes, the deterministic way of preventing this is by not using Thread.Abort. Ever. Signal to your threads that is is time to stop, and let them terminate gracefully. Thread.Abort is a great big red-herring, placed in the API solely to trip you up. ;)
http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation
There is a tradeoff.
Be sure to close all resources immediately, even in the presence of ThreadAbortException
Have simpler code, but temporarily leak resources if Abort() is called
I assume that you are not calling Abort, and just want a way to be safe if someone else does. If you are calling Abort, then I'd advise that you don't. This isn't the only problem you will run into. There are other problems with Abort in the documentation.
#2 is a valid choice because callers of Abort() should expect this.
If you want to choose #1, then I don't think even a simple try/catch will help. If the ThreadAbortException can happen everywhere, then it can still happen after the file is opened (inside File.OpenWrite()) and before you can assign it to a variable that you can call Dispose() on -- you will have the same problem as using in your code.
You need semantics like
using (var handle = GetUnOpenedHandle()) {
handle.Open(); // this can't involve assignment to any field of handle
}
I'm not sure this is possible.
In many cases (but definitely not all) you could guard against a ThreadAbortException. Most of the critical code in the .NET BCL does this fairly well already. The problem is that it is really hard to get right. And for this reason most people recommend, and rightly so, to avoid aborting threads. Starting in version 2.0 the CLR made thread aborts a lot more tolerable and introduced a new set of APIs to help code authors guard against them. Take a look at Constrained Execution Regions for an in depth look at how all of this works.
I believe you are correct about your concerns with the example of the using block. For constrained execution regions to work correctly the out-of-band (asynchronous) exception must occur from within a try block. But, because of the way using expands out the expression is evaluated outside of the try block. Contrast that with the expansion of the lock block which evaluates the expression from within the try block. Well, that is true with version 4.0 of the framework anyway and that was changed specifically to guard against these exceptions.
So the question is why was the same change not made with the using block. According to Joe Duffy this was an acceptable omission because the assumption is that thread aborts should always be followed by a termination of the AppDomain which would fire off the finalizers anyway.
So yes. Your code is not tolerant of out-of-band (asynchronous) exceptions. But, the prevailing wisdom from those smarter than me is that it should not have to be.
A thread abort is most often used in the case of a fatal error, so your response should probably be to let your application terminate. If your trying to stop your own threads cleanly, use Thread.Join().
Is there any even small possibility that finally will not be invoked but application still be running?
I'm releasing semaphore there
finally
{
_semParallelUpdates.Release();
}
and afraid of lost of some of them.
Only critical finalizers have a strong guaranty to be called in case the shit hits the fan. You can inherit from CriticalFinalizerObject or SafeHandle to get this behavior. However, letting your finalizer do anything else than call code with a strong reliability contract is not advised. This code has to be able to run for instance, in situations where the system is out of memory.
Implementing a critical finalizer is only needed in situations where you want to be sure all unhandled resources are cleaned even if the app domain is unloaded (because for instance). Please note that you of course never have any guarantee that finalizers will run. In case of a power failure, you're out of luck. If you need more guarantees, you need some sort of transactional system (such as a database) that can get you this behavior.
If you are looking for ways to make your code reliable, I suggest reading the following article:
Reliability Best Practices
Another excellent article recommended by VinayC is the following:
Stephen Toub: Keep Your Code Running with the Reliability Features of the .NET Framework
Host windows operating system will terminate the program even in worst cases of uncaught fatal exceptions. But yes even in that case finally block will surely get executed.
In Framework 1.0 and 1.1, this was possible if a thread which is currently in the finally block was aborted using Thread.Abort. In current versions of the framework, I'm not aware of any such cases.
Is it guaranteed that your code will reach the finally? Yes (barring some cataclysmic event such as the world coming to an end... or, you know, your computer losing power or your OS crashing).
But it's important to recognize that, if it's absolutely critical that your code runs, you better make sure your code doesn't throw an exception itself!
Take this for example:
IDisposable someDisposableObject = null;
IDisposable someOtherDisposableObject = null;
try
{
someDisposableObject = GetDisposableObject();
throw new Exception("Holy crap, something bad happened.");
someOtherDisposableObject = GetOtherDisposableObject();
}
finally
{
// This will throw a NullReferenceException...
someOtherDisposableObject.Dispose();
// ...so this actually won't run.
someDisposableObject.Dispose();
}
So if you want your entire finally block to be run, it's important to write it properly so that an exception is (ideally) impossible.
The current thread will not leave the current stack frame unless or until the "finally" block executes or an exception is thrown from within the finally block itself. If a thread dies or gets blocked within a "try" block, execution will never leave the current stack frame, but it won't execute the finally "block" either.
I have a program that will analyzes source code. It can recursively go through a directory to find all projects, and then recursively go through the project to find all source code.
I want to create a cancel process button, which allows the user to stop the code parsing. I run the code parsing in a background worker. I want to be able to watch for the cancel event.
The problem is figuring out how to edit my code so that it will go and check that item and return back to the GUI. The parsing process goes several methods deep.
In a much smaller process, I successfully use a thread-safe singleton that has a bool that says whether or not a cancel has been requested, and stop the loop where it is running.
What would be the best way of working this cancel request into my code?
EDIT: Here is an idea, inspired by John Saunders' answer.
What if I run a background thread in my processing thread that watches for the Cancel Singleton to change, and then throw an exception from that process? Does this seem like good practice? This does not work as intended
EDIT 2: John Saunders' answer seems to be the best for now. I will just throw my own exception when the Singleton is true for now. I'll wait to see if any other solutions are proposed
Thread.Abort is a bad idea, as it interrupts the thread at an arbitrary point - probably interrupts it where you'd least like to be interrupted.
Set a flag that it seen by the thread being cancelled. Check it at the beginning of each operation. The idea would be to identify places in the code where it is safe to stop, and to check the flag at only those points.
You may find it useful to throw an exception at those points. The exception should be one that is not caught by your code until it reaches the boundary between your code and the UI. At that point, your code would simply return.
You could use the Thread.Abort() function on your background worker thread. This throws a ThreadAbortException which you can catch in any of your methods but which will atomatically be rethrown at the end of the catch blocks.
Also all finally-blocks will be executed.
It sounds like you're using the .NET backgroundworker class. I think you can pass a object parameter into the RunWorkerAsync method which then becomes accessible to the background thread in the DoWork event handler argument.
You could then modify that object in the UI thread (for example update a boolean cancel property) and periodically check on it from your background process.
There are various ways to perform a cancel on threaded operations; all of which involve the periodic checking of a flag or other value to determine if the thread should continue operating or not.
I would not recommend throwing exceptions for this feature. First of all, cancelling is not an exceptional circumstance, and second, it's overkill for what you're trying to implement.
Instead, you could use a simple, thread-safe boolean flag as a static member of a class accessible from any thread, or use a synchronization object such as a named Mutex. Signalling the synchronization object would then allow the thread to know it must cancel.