【问题标题】:Mutex c# Safe handle has been closedMutex c#安全句柄已关闭
【发布时间】:2014-12-15 13:49:06
【问题描述】:

这是我的代码使方法调用互斥

public class X
{
    private static Mutex mutex = new Mutex(true, "MutexForFile");
    public IList<string> DoIt(IList<string> documents)
    {
        var result = new List<string>();
        if (mutex.WaitOne())
        {
            using (var agent = new MyClass())
            {
                // operation login
                if (agent.LibraryLogon("**", "***"))
                {
                    try
                    {
                        //codes to access shared resource
                    }
                    catch (Exception e)
                    {
                        Log.ErrorFormat("");
                    }
                    finally
                    {
                        if (!mutex.SafeWaitHandle.IsClosed)
                        {
                            mutex.ReleaseMutex();
                        }
                        mutex.Dispose();
                    }
                    Log.DebugFormat("Completed");

                }
                else
                {
                    throw new Exception("Unable to Login Session");
                }
            }
            Log.DebugFormat("Completed Do it");
        }
        return result;
    }
}

我不得不检查 if (!mutex.SafeWaitHandle.IsClosed),因为当我调用 mutex.ReleaseMutex() 时收到 ObjectDisposedException 说“安全句柄已关闭”。

这是避免这种异常的正确方法吗?

任何一次都可以表明此代码存在任何缺陷或问题吗?

【问题讨论】:

  • 我建议阅读 MSDN 上有关构造函数的 Mutex 类的文档。特别是Mutex(bool initiallyOwned, string name)Mutex(bool initiallyOwned, string name, out bool creatNew) 最简单的解决方法可能是使用 intiallyOwned = false 而不是 true 来初始化互斥锁。然后,您应该能够在 finally 语句中删除 if 块。我还没有验证这一点,而且我已经很长时间没有使用 .Net 互斥锁了,但是,我认为这将解决问题。根据您对互斥锁的全部使用情况,您可能需要进行更多处理。
  • 为方便起见的文档:msdn.microsoft.com/en-us/library/…
  • 我试过这个,但对我没有帮助
  • 在你调用了 mutex.Dispose() 之后,你再也不能使用 X 类了。无论如何,您都会这样做,这就是导致异常的原因。您还在摸索 ReleaseMutex() 调用,它必须在您调用 WaitOne() 后无条件调用。代码从根本上以不止一种方式被破坏,显然你必须重新考虑这一点。
  • 我应该如何重新排列这些代码?

标签: c# .net mutex


【解决方案1】:

您应该避免在另一个线程等待它时释放互斥锁:

Thread #1: WaitOne() -> gets ownership
Thread #2: WaitOne() -> waits for thread #1
Thread #1: ReleaseMutex() -> causes thread #2 to continue
Thread #1: Dispose()
Thread #2: ReleaseMutex() -> mutex was disposed by thread #1

SafeWaitHandle.IsClosed 只是防止出现异常,但不能解决根本问题。它只能在产生这些线程的代码中解决,而不是在线程内解决 - 也许您不应该有多个线程同时尝试登录?

【讨论】:

  • 我可以在msdn.microsoft.com/en-us/library/…看到类似的东西
  • 我不确定应该在哪里调用 ReleaseMutex 和 Dispose 方法。谁能告诉我?
  • @KuttanSujith 我不知道你为什么首先需要Mutex - 你为什么要让多个线程执行这个操作?
  • @C.Evenhuis: 多线程不应该执行这个操作。这就是我使用互斥锁的原因
  • @KuttanSujith 垃圾收集器会自动处理Mutex,我并不是要强调“你的程序结束”这样,我只是想说明你不应该 处置Mutex,除非你确定你不会再次使用它。
猜你喜欢
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
相关资源
最近更新 更多