我有以下代码:
using (Mutex mut = new Mutex(false, MUTEX_NAME))
{
if (mut.WaitOne(new TimeSpan(0, 0, 30)))
{
// Some code that deals with a specific TCP port
// Don't want this to run at the same time in another process
}
}
我已经在里面设置了一个断点if
块,并在 Visual Studio 的另一个实例中运行相同的代码。正如预期的那样,.WaitOne
调用块。然而,令我惊讶的是,当我continue在第一个例子中和using
块终止时,我在第二个进程中收到有关废弃互斥体的异常。
修复方法是调用ReleaseMutex
:
using (Mutex mut = new Mutex(false, MUTEX_NAME))
{
if (mut.WaitOne(new TimeSpan(0, 0, 30)))
{
// Some code that deals with a specific TCP port
// Don't want this to run twice in multiple processes
}
mut.ReleaseMutex();
}
现在,一切都按预期进行。
我的问题:通常一个点IDisposable
is it 清理无论你把东西放在什么状态。我可以看到也许有多个waits and releases在一个using
块,但是当互斥体的句柄被释放时,它不应该自动释放吗?换句话说,为什么我需要打电话ReleaseMutex
如果我在using
block?
我现在还担心如果代码中if
块崩溃,我会放弃周围的互斥体。
放置有什么好处吗Mutex
in a using
堵塞?或者,我应该只是new up a Mutex
实例,将其包装在 try/catch 中,然后调用ReleaseMutex()
内finally块(基本上完全实现了我的thought Dispose()
会做)
文档 http://msdn.microsoft.com/en-us/library/f55ddskf(v=vs.110).aspx解释(在“备注”部分)两者之间存在概念差异实例化一个 Mutex 对象(它的作用是not,事实上,就同步而言,做任何特别的事情)并且获取互斥体(使用WaitOne http://msdn.microsoft.com/en-us/library/cc190477(v=vs.110).aspx)。注意:
-
WaitOne
返回一个布尔值,这意味着获取互斥体可以fail(超时)两种情况都必须处理
- When
WaitOne
回报true
,则调用线程已获取互斥体并且must call ReleaseMutex
,否则互斥体将被废弃
- 当它返回时
false
,然后是调用线程must not call ReleaseMutex
因此,互斥锁不仅仅是实例化。至于是否应该使用using
无论如何,让我们看看是什么Dispose
确实(如继承自WaitHandle http://msdn.microsoft.com/en-us/library/System.Threading.WaitHandle(v=vs.110).aspx):
protected virtual void Dispose(bool explicitDisposing)
{
if (this.safeWaitHandle != null)
{
this.safeWaitHandle.Close();
}
}
正如我们所看到的,互斥锁是not已发布,但涉及一些清理工作,所以坚持使用using
将是一个很好的方法。
至于你应该如何进行,你当然可以使用try/finally
块以确保在获取互斥体时能够正确释放它。这可能是最直接的方法。
If you really不关心互斥体无法获取的情况(您没有指出,因为您传递了一个TimeSpan
to WaitOne
),你可以换行Mutex
在你自己的类中实现IDisposable
,在构造函数中获取互斥体(使用WaitOne()
不带任何参数),然后在内部释放它Dispose
。虽然,我可能不会推荐这样做,因为如果出现问题,这会导致您的线程无限期地等待,并且无论有充分的理由 https://stackoverflow.com/a/25433661/716118用于在尝试获取时显式处理这两种情况,如@HansPassant所述。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)