TN.*_*TN. 21 c# pinvoke synchronization mutex handle
如何从C#中的互斥锁中找到获取互斥锁的?
如果mutex.WaitOne(timeout)超时,则返回false.但是,如何从互斥锁手柄中找到它?(也许使用p/invoke.)
更新:
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
}
Run Code Online (Sandbox Code Playgroud)
目前,我正在使用自己的属性IsAcquired来确定是否应该释放互斥锁.不是必要但更清楚,不是使用IsAcquired属性所代表的信息的二级副本,而是直接询问互斥是否是我获得的.mutex.ReleaseMutex()如果我没有获得,则调用会抛出异常.
(通过获取状态,我的意思是当我拥有互斥锁时,互斥锁处于未发出信号状态.)
(编辑:我IsAcquired = false;感谢mattdekrey的帖子.)
Kar*_*ngs 13
有没有干净的方式来做到这一点的原因是因为它不是一个好主意,原因是因为争用情况是-very-容易,当你依靠这种类型的逻辑来介绍.所以你的设计需要改变.
首先,您不应该在构造函数中获取锁.将此类转换为返回正确初始化的互斥对象的工厂.这样你就可以知道你是否获得了锁.
不要依赖Dispose释放锁,这就是要求死锁的代码很难维护.使用try/finally块确保它被释放.
超时有点粗略.仅在未获取锁定时使用超时将被视为正常操作.无法获取锁通常是一个错误,只是通过超时避免它隐藏了错误.如果您需要超时,请考虑使用事件(可能是AutoResetEvent),这可能更合适.
小智 5
您可能会发现,Mutex该类上没有公共成员:http :
//msdn.microsoft.com/zh-cn/library/system.threading.mutex_members.aspx
也没有为此提供的公共本机功能:http : //msdn.microsoft.com/zh-cn/library/ms686360%28v=VS.85%29.aspx
但是,有一些未记录/不支持的功能,尤其是在中ntdll.dll。这些允许访问系统对象。但是,这些功能可能会更改或在将来的操作系统版本中不可用。
因此,答案是:使用常规手段是不可能的。