【发布时间】:2010-02-04 16:05:05
【问题描述】:
我有几段代码需要使用 Mutex 进行保护。问题是代码看起来像这样:
lock(mylockobject) {
if(!foo())
throw new MyException("foo failed");
if(!bar())
throw new MyException("bar failed");
}
使用锁,它可以按我的意愿工作,但现在我需要使用互斥锁。这里明显的问题是,如果我获取互斥锁并且 foo() 或 bar() 失败,我必须在抛出每个异常之前显式释放互斥锁。
在 C++ 中,我将利用在堆栈上创建的对象的范围,并将互斥锁锁定在对象的构造函数中,然后在析构函数中释放它。使用 .NET 的垃圾收集,我认为这行不通。我编写了一个测试应用程序并确认如果我这样做:
public class AutoMutex
{
private Mutex _mutex;
public AutoMutex(Mutex mutex)
{
_mutex = mutex;
_mutex.WaitOne();
}
~AutoMutex()
{
_mutex.ReleaseMutex();
}
}
然后有这样的代码:
// some code here...
Mutex my_mutex = new Mutex(false, "MyMutex");
{ // scoping like I would do in C++
AutoMutex test = new AutoMutex(my_mutex);
test = null;
}
析构函数(终结器?)直到很久以后才会被调用。
Google 还没有为我指出正确的方向,但我仍在努力……如果可能的话,请告诉我你如何解决这个小问题。
【问题讨论】:
-
这里的 C++ 模式名称是“Resource Acquisition Is Initialization”,通常称为“RAII”。例如,如果您搜索“C# 中的 RAII”,您会找到 blogs.msdn.com/colinth/archive/2007/08/08/…。在 C# 中,我们调用“一次性模式”,例如,您可以阅读 msdn.microsoft.com/en-us/library/fs2xkftw.aspx。沿着这些思路,您还应该阅读有关
try-finallymsdn.microsoft.com/en-us/library/zwc8s4fz.aspx 的信息。最后,不要扔进处于不良状态的保护区内。
标签: c# garbage-collection locking