如何从C#中的互斥锁句柄中发现已获取互斥锁?
但是,我如何从互斥处理中找到它呢?
更新
public class InterProcessLock : IDisposable
{
readonly Mutex mutex;
public bool IsAcquired { get; private set; }
public InterProcessLock(string name, TimeSpan timeout)
{
bool created;
var security = new MutexSecurity();
security.AddAccessRule(new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow));
mutex = new Mutex(false, name, out created, security);
IsAcquired = mutex.WaitOne(timeout);
}
#region IDisposable Members
public void Dispose()
{
if (IsAcquired)
{
mutex.ReleaseMutex();
IsAcquired = false;
}
}
#endregion
}
目前,我正在使用自己的属性IsAcquired
来确定是否应该释放互斥锁。不是必须的,但更清楚的是,不使用由IsAcquired
属性表示的信息的辅助副本,而是直接询问互斥锁是否由我获取。因为调用mutex.ReleaseMutex()
会抛出一个异常,如果我没有获取它。
(我所说的获取状态是指当我拥有互斥锁时,互斥锁处于无信号状态。)
(编辑:多亏了mattdekrey's post,我添加了IsAcquired = false;
。)
发布于 2010-06-22 17:21:01
正如您可能发现的,在Mutex
类上没有公共成员:http://msdn.microsoft.com/en-us/library/system.threading.mutex_members.aspx
也没有用于此的公共本机函数:http://msdn.microsoft.com/en-us/library/ms686360%28v=VS.85%29.aspx
但是,有一些未记录的/不受支持的函数,尤其是在ntdll.dll
中。它们允许访问系统对象。但是,这些功能可能会更改或在未来版本的操作系统中不可用。
因此,答案是:使用传统方法是不可能的。
发布于 2010-06-12 03:13:51
所以你的设计需要改变。
首先,您不应该在构造函数中获取锁。将这个类转换成一个工厂,返回一个正确初始化的互斥对象。这样你就可以知道你是否获得了锁。
不要依赖Dispose来释放锁,这是在要求很难维护的死锁代码。使用try/finally块来确保它被释放。
超时有点粗略。只有在没有获得锁的情况下才使用超时将被认为是正常操作。不能获得锁通常是一个bug,仅仅通过超时来避免它会隐藏这个bug。如果您需要超时,请考虑使用事件(可能是AutoResetEvent),这可能更合适。
发布于 2010-06-11 01:03:42
好吧,这并不完全是您所要求的,但是我认为它可以解决您的问题:为什么不专门为其他人获取Mutex时发生的异常添加一些错误处理?
public void Dispose()
{
if (IsAcquired)
try
{ mutex.ReleaseMutex(); }
catch (System.Threading.SynchronizationLockException)
{
// Handle the exception, assuming you need to do anything.
// All other exceptions would still be passed up the stack.
}
}
https://stackoverflow.com/questions/3013212
复制相似问题