如何在C#中找到Mutex?

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),这可能更合适.

  • Matt - http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx:"不要以为会调用Dispose." 你是对的,只要开发人员将它放在一个使用块中或手动调用dispose就可以了.但这很尴尬.许多人会假设终结者(或者更可能只是没有线索......)并且让它失去范围.这不适用于锁,因为GC可能会或可能不会立即收集对象,从而导致锁定时出现奇怪现象.它很难找到bug.它可以工作,但它为简单的锁添加了"以这种方式"处理开销.最好让锁像锁一样. (3认同)

小智 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。这些允许访问系统对象。但是,这些功能可能会更改或在将来的操作系统版本中不可用。

因此,答案是:使用常规手段是不可能的。