Here’s another little “gotcha” from my experimentations in running C# apps cross-platform. The following code implements a system-wide mutex to ensure that only one instance of the program is running at any one time:
public static void Main(string[] args){ Mutex mutex = null; try{ mutex = Mutex.OpenExisting("test.martyndavis.com"); // if we *can* open it we're an ADDITIONAL instance Console.WriteLine("Application is already running"); return; } catch(WaitHandleCannotBeOpenedException){ // if we get in here then the mutex doesn't exist, // so we are the only instance running on this machine mutex = new System.Threading.Mutex(true, "test.martyndavis.com"); } try{ Console.WriteLine("Doing stuff... press a key"); Console.Read(); } finally{ // Although mutex implements IDisposable, it doesn't // call Release Mutex when being Disposed(), // hence usage of try/finally instead of 'using'. mutex.ReleaseMutex(); } }
Running this on Windows it behaves as one would expect. Run one instance you get “Doing stuff… press a key” output, and, if you try to run a second instance in another DOS box you get “Application is already running”.
On Linux though it’s a different story – each instance runs as if it’s the only copy on the machine.
Doing some digging turns up this note in Mono’s release docs – you can see that shared handles are now turned off by default – you can turn them on by setting the environment variable MONO_ENABLE_SHM, but for the application I’m working on I think I’ll simply avoid mutexes and use something else to ensure one instance – a lock file in the application’s data directory will be simple, and work cross-platform.
Zoltan Varga 2016-03-23 18:12:22 UTC
This functionality was removed as the implementation was very complicated and error prone on unix.
https://github.com/mono/website/commit/ad30bfa1b33dd8d07a063c40ce44dcecb49e8f54
Thanks for the update Alberto!