AbandonedMutexException: The wait completed due to an abandoned mutex - c#

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:"

Related

Get an exception when acquiring mutex after a service restart

I'm writing a windows service with c#. It reads continuously from a MSMQ by calling Read() from a thread :
public string Read()
{
try
{
if (!readMutex.WaitOne(100))
{
return null;
}
var message = queue.Receive();
return (string)message.Body;
}
catch (Exception ex)
{
logger.Error("Exception:" + ex);
}
finally
{
readMutex.ReleaseMutex();
}
return null;
}
The mutex is created in the class constructor and disposed in the destructor.
The problem is that, after I stop and restart the service, I always get a AbandonedMutexException at the if (!readMutex.WaitOne(100)) the first time Read() is called.
After attaching a debugger and adding breakpoints, I found that when the service is stopped, the finally block is never entered, I'm not sure if that would be the problem.
It's maybe not a big problem because the next time Read() is called, the exception is no longer raised. But I'm wondering is there's a simple way to solve this?
Append 1 :
I found that destructor is always called when the service is stopped, so I tried release mutex in the destructor. But found that I'm not allowed to release it ,because the mutex seems to be acquired in a different thread context.
Append 2:
For those who are interested in this question, I'll add what I've found after examining what's going on.
I tested that if I create a program which acquires a mutex without releasing it, and then close the program, the next time the program run, it can still acquire the mutex successfully without any exception. This is contradictory to this problem's symptom, and also contradictory to what I used to think.
I think the truth is that the OS close the mutex for me when the program quits, so next time I can acquire it.
But why I failed with this service? Finally I found that I had another second service which also created this path's mutex. That second service just kept a mutex handle, without doing anything to it(e.g. waiting on it ). In this case, when my first service restart and try acquire the Mutex again, it gets the exception.
In conclusion, when the program terminates with an unreleased mutex:
1) if the mutex is also referenced by any other services/applications, then next time the mutex is acquired, an exception will be raised.
2) if it's the only program referencing this mutex, then the os will handle this gracefully for me, and no error will be reported at next acquisition.
readMutex.ReleaseMutex(); is most likely never being called when the service shuts down
More so, Receive blocks until it receives a message, so its likely that when the service is shutting down it times out, thinks that is has hang, and kills the process without closing gracefully.
There are several approaches here,
You are probably better to call MessageQueue.Receive Method (TimeSpan) with a short timeout, and adjust your logic accordingly, this way (on shut down) the receive will hopefully timeout before the service timesout.
The other approach is running this in a thread or task and killing it on the shutdown and make sure you call readMutex.ReleaseMutex()
Anyway you have enough information now, and you should be able to solve this in a way that suits you

Is ReaderWriterLockSlim resistant to ThreadAbortException?

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().

Revisiting Thread.Abort() - is it safe?

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.

What is the recommended way to guard against resource leaks in the context of ThreadAbortException?

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().

.NET Mutex on windows platform: What happens to them after I'm done?

I've got a simple .NET program, which checks to see if another instance has been started:
Mutex mutex = new Mutex(false,"MyMutexName");
if (!mutex.WaitOne(1))
return;
try{
//do stuff
}
catch{ //exceptions}
finally
{
mutex.ReleaseMutex();
}
My question is, what exactly happens to the mutex if you forget to release it when the program ends? Is it visible in some windows control panel component? Where does it live?
It is a named mutex so it is visible and can be opened in other processes. Windows uses a simple reference count on the handle. If you don't Dispose() it explicitly yourself then the finalizer will close the handle for you. If your program bombs hard and never executes the finalizer then Windows will do it when it cleans up the resources used by your program.
That will automatically decrement the reference count. If that counts down to zero (no other processes have a handle open on it) then the kernel object is released.
In other words: you don't have a problem no matter how badly things turn out. The actual mutant object lives in the kernel memory pool. You can see it with the SysInternals' WinObj tool.
From MSDN
If a thread terminates while owning a
mutex, the mutex is said to be
abandoned. The state of the mutex is
set to signaled and the next waiting
thread gets ownership. If no one owns
the mutex, the state of the mutex is
signaled. Beginning in version 2.0 of
the .NET Framework, an
AbandonedMutexException is thrown in
the next thread that acquires the
mutex. Prior to version 2.0 of the
.NET Framework, no exception was
thrown.
Caution
An abandoned mutex often indicates a
serious error in the code. When a
thread exits without releasing the
mutex, the data structures protected
by the mutex might not be in a
consistent state. The next thread to
request ownership of the mutex can
handle this exception and proceed, if
the integrity of the data structures
can be verified.
In the case of a system-wide mutex, an
abandoned mutex might indicate that an
application has been terminated
abruptly (for example, by using
Windows Task Manager).
Mutexes are OS-level handles. They'll get closed when your process does (if you don't close them sooner, that is.)
edit
Ok, I clearly misunderstood the example and the question. If you're just trying to detect whether another instance exists, you'd create a named mutex (or similar object) and simply check for its existence without ever locking on it.
The call to WaitOne locks on it, taking ownership, while ReleaseMutex gets rid of it (so long as there are no additional calls to WaitOne). If you end the thread without releasing the mutex fully, it does leave the object in a bad state, as explained in the text Micah quotes.
I took your question as being about whether you close the handle before the process completes, which is another thing entirely.
additional
At the SDK [API][1] level, you can call CreateMutex with the expectation of failing when a mutex of the same name has already been created. In .NET (well, in 4.0, at least), there's a [constructor][2] that fills a createdNew bool.
[1]: http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx CreateMutex
[2]: http://msdn.microsoft.com/en-us/library/bwe34f1k(v=VS.90).aspx Mutex

Categories

Resources