首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何发现C#中的互斥是被获取的?

如何发现C#中的互斥是被获取的?
EN

Stack Overflow用户
提问于 2010-06-10 17:35:00
回答 6查看 22.8K关注 0票数 25

如何从C#中的互斥锁句柄中发现已获取互斥锁?

但是,我如何从互斥处理中找到它呢?

更新

代码语言:javascript
复制
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;。)

EN

回答 6

Stack Overflow用户

回答已采纳

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

因此,答案是:使用传统方法是不可能的。

票数 7
EN

Stack Overflow用户

发布于 2010-06-12 03:13:51

所以你的设计需要改变。

首先,您不应该在构造函数中获取锁。将这个类转换成一个工厂,返回一个正确初始化的互斥对象。这样你就可以知道你是否获得了锁。

不要依赖Dispose来释放锁,这是在要求很难维护的死锁代码。使用try/finally块来确保它被释放。

超时有点粗略。只有在没有获得锁的情况下才使用超时将被认为是正常操作。不能获得锁通常是一个bug,仅仅通过超时来避免它会隐藏这个bug。如果您需要超时,请考虑使用事件(可能是AutoResetEvent),这可能更合适。

票数 14
EN

Stack Overflow用户

发布于 2010-06-11 01:03:42

好吧,这并不完全是您所要求的,但是我认为它可以解决您的问题:为什么不专门为其他人获取Mutex时发生的异常添加一些错误处理?

代码语言:javascript
复制
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.
        }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3013212

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档