The Mutex class is very misunderstood, and Global mutexes even more so.
What is good, safe pattern to use when creating Global mutexes?
The Mutex class is very misunderstood, and Global mutexes even more so.
What is good, safe pattern to use when creating Global mutexes?
I really want to make sure this is out there, cause its so hard to get right.
// unique id for global mutex - Global prefix means it is global to the machine
const string mutex_id = "Global\\{B1E7934A-F688-417f-8FCB-65C3985E9E27}";
static void Main(string[] args)
{
using (var mutex = new Mutex(false, mutex_id))
{
// edited by Jeremy Wiebe to add example of setting up security for multi-user usage
var allowEveryoneRule = new MutexAccessRule("Everyone", MutexRights.FullControl, AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(allowEveryoneRule);
mutex.SetAccessControl(securitySettings);
//edited by acidzombie24
var hasHandle = false;
try
{
try
{
// note, you may want to time out here instead of waiting forever
//edited by acidzombie24
//mutex.WaitOne(Timeout.Infinite, false);
hasHandle = mutex.WaitOne(5000, false);
if (hasHandle == false) return;//another instance exist
}
catch (AbandonedMutexException)
{
// Log the fact the mutex was abandoned in another process, it will still get aquired
}
// Perform your work here.
}
finally
{
//edit by acidzombie24, added if statemnet
if(hasHandle)
mutex.ReleaseMutex();
}
}
}
Would this be the right way of doing the same thing with a timeout ?
// unique id for global mutex - Global prefix means it is global to the machine
const string mutex_id = "Global\\{B1E7934A-F688-417f-8FCB-65C3985E9E27}";
static void Main(string[] args)
{
using (var mutex = new Mutex(false, mutex_id))
{
bool bHadMutex = false;
try
{
try
{
// note, you may want to time out here instead of waiting forever
bHadMutex = mutex.WaitOne(200, false);
}
catch (AbandonedMutexException)
{
// Log the fact the mutex was abandoned in another process, it will still get aquired
bHadMutex = true;
}
// Perform your work here.
}
finally
{
// ReleaseMutex will throw ApplicationException if the calling thread does not own the mutex, so we have to check
if (bHadMutex)
mutex.ReleaseMutex(); // otherwise
}
}
}
This example will exit after 5 seconds if another instance is already running.
// unique id for global mutex - Global prefix means it is global to the machine
const string mutex_id = "Global\\{B1E7934A-F688-417f-8FCB-65C3985E9E27}";
static void Main(string[] args)
{
using (var mutex = new Mutex(false, mutex_id))
{
try
{
try
{
if (!mutex.WaitOne(TimeSpan.FromSeconds(5), false))
{
Console.WriteLine("Another instance of this program is running");
Environment.Exit(0);
}
}
catch (AbandonedMutexException)
{
// Log the fact the mutex was abandoned in another process, it will still get aquired
}
// Perform your work here.
}
finally
{
mutex.ReleaseMutex();
}
}
}