Archive for November, 2008
Either no one reads my blog or I didn’t present the problem good enough. The first is probably the safest bet. But here’s the answer anyway.
I made a small hint about it was run on a terminal (meaning I’m logged in as a user on a Windows Server with Terminal Services running (just to be clear)).
So lets look at what possible smells we can find in the code:
That application specific GUID sure seems like it can be trouble.
Hmm, the GUID is now used as the name for this Mutex. And now the last piece of the puzzle:
Ok, this sure works when I’m sitting alone on my computer with my application, but what happens when multiple users on a terminal server tries to start the same application?
Multiple NamedPipeServerStreams with the same identifier will be tried made, and then you will get: “IOException: All pipe instances are busy.” But shouldn’t it stop at the Mutex before it tries to make the server? After all, the named Mutex is using the same GUID as identifier as well.
It seems that the assumption that the Mutex and the named pipe operated on the same system level are flat out wrong. They don’t!
You can prefix your mutex identifier with Global\ to ensure a system wide lock even on a terminal services system, but this isn’t really what we want in this situation. We would really like all users to get a single instance each.
With the problem identified, the solution was easy. We just incorporated the logged in username into the identifier, and everything was humming along.
Until next mystery, go solve some yourselves.
There are a lot of ways to make sure your .NET Windows application just has one instance running, and we picked the one described here. It was working flawlessly until someone tried running it on a terminal where it crashed mysteriously.
What happened? Can you spot the error?