是否正确实施了互斥锁,如何处理它?

时间:2009-09-25 14:18:25

标签: .net dispose mutex idisposable waithandle

我正在审查一些代码,其中一个代码分析(fxCop)警告让我非常困惑。该代码通过在类的开头创建变量来实现一些mutex,类似于:

private Mutex myMutex = new Mutex();

fxCop弹出一条消息说我必须为类实现IDisposable,因为Mutex类实现了它 - 这是警告CA1001。但是看看Mutex它没有处理方法。

事实证明,Mutex使用SafeWaitHandle(实现IDisposable - 猜测这是fxCop正在拾取的东西),但是互斥体实际上并没有通过标准的一次性模式处理它。它有一个私有方法,使用RuntimeHelpers.CleanupCode分配给委托,据我所知,这意味着它将在异常上运行。

这提出了两个问题:

  1. Mutex是否正确实施?如果Mutex中没有例外,那么SafeWaitHandle永远不会被处理掉。
  2. 我应该如何处理清理互斥锁?

2 个答案:

答案 0 :(得分:5)

Mutex 通过其基类IDisposable.Dispose显式实现 WaitHandle。它通过公共Dispose方法(也继承自Close)公开了WaitHandle功能,这是一种有效的配置模式实现,according to the guidelines

  

偶尔会有一个特定于域的名称   比Dispose更合适。对于   例如,文件封装可能   想要使用方法名称关闭。在   这种情况下,私下实现Dispose   并创建一个公共Close方法   调用Dispose。 (...)你   可以使用方法名称替换Close   适合您的域名。

System.IO中的几个班级也是这样做的。

答案 1 :(得分:0)

使用Close()函数仍会在VS 2013 Pro Update 2下生成CA2000。 由于其保护级别,无法访问Dispose()函数。

那么,是否存在错误,或者这是VS的代码分析中的错误?

编辑: 解决了使用此代码:

Mutex MyApplicationMutex = null;
try
{
  MyApplicationMutex = new Mutex(true, Program.g_ApplicationMutexName);
  if (MyApplicationMutex.WaitOne(0, false))
  {
    ...
  }
}
finally
{
  // Dispose Mutex
  if (MyApplicationMutex != null)
    MyApplicationMutex.Close();
 }