There are quite few interesting blogs that go on this topic and here I would like to show a manager class I use (even on terminal services) in my code. Notice that I'm prefixing Global in cases where I want it to be visible for all terminal server sessions; otherwise it's per user session (common usage). Take a look:
using System;
using System.Threading;
namespace myNameSpace
{
/// <summary>
/// MutexManager to support safe Mutex implementation
/// Be sure to check for IsMutexCreated
/// </summary>
public class MutexManager : IDisposable
{
#region Private Properties
private bool disposed = false;
private Mutex _Mutex;
#endregion Private Properties
#region Public Properties
public bool IsMutexCreated { get; private set; }
public bool HasException
{
get { return (ExceptionText != null && ExceptionText.Length > 0); }
}
public string ExceptionText { get; private set; }
#endregion Public Properties
/// <summary>
/// Instantiates the MutexManager with the WaitOne.
/// Check for IsMutexCreated to make sure whether to continue
/// </summary>
/// <param name="handleName">Unique name for each handler</param>
/// <param name="isGlobal">Set to true when using this for Terminal Services</param>
/// <param name="synchronizeRequest">Set to true when the request needs to be synchronized.</param>
public MutexManager(string handleName, bool isGlobal, bool synchronizeRequest)
{
try
{
IsMutexCreated = true;
bool isNewMutexCreated = false;
// Look for global
if (isGlobal)
handleName = @"Global\" + handleName;
//
_Mutex = new Mutex(false, handleName, out isNewMutexCreated);
//
IsMutexCreated = (isNewMutexCreated || synchronizeRequest);
if (IsMutexCreated)
isNewMutexCreated = _Mutex.WaitOne();
}
catch (UnauthorizedAccessException accessException)
{
IsMutexCreated = false;
ExceptionText = accessException.Message;
}
catch (AbandonedMutexException abandonedMutex)
{
IsMutexCreated = false;
ExceptionText = abandonedMutex.Message;
}
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
try { _Mutex.ReleaseMutex(); }
catch { }
disposed = true;
}
}
~MutexManager()
{
Dispose(false);
}
#endregion IDisposable Members
}
}
When to consume, I then use it like:
using (MutexManager mutexManager =
new MutexManager("my unique handler name", true, false))
{
// Mutex has exception?
if (mutexManager.HasException)
log(mutexManager.ExceptionText);
// Not synchronizing the Mutex ==> check for whether to continue
if (!mutexManager.IsMutexCreated)
return;
// do work
}
Love coding!
No comments:
Post a Comment