我有一堆属性,我将在这些属性上使用读/写锁。我可以使用try finally或using子句来实现它们。
在try finally中,我会在try之前获取锁,然后在finally中释放。在using子句中,我将创建一个类,该类在其构造函数中获取锁,并在其Dispose方法中释放。
我在很多地方使用读/写锁,所以我一直在寻找比try finally更简洁的方法。我有兴趣听到一些关于为什么一种方法可能不被推荐,或者为什么一种方法可能比另一种更好的想法。
方法1 (try finally):
static ReaderWriterLock rwlMyLock_m = new ReaderWriterLock();
private DateTime dtMyDateTime_m
public DateTime MyDateTime
{
get
{
rwlMyLock_m .AcquireReaderLock(0);
try
{
return dtMyDateTime_m
}
finally
{
rwlMyLock_m .ReleaseReaderLock();
}
}
set
{
rwlMyLock_m .AcquireWriterLock(0);
try
{
dtMyDateTime_m = value;
}
finally
{
rwlMyLock_m .ReleaseWriterLock();
}
}
}方法二:
static ReaderWriterLock rwlMyLock_m = new ReaderWriterLock();
private DateTime dtMyDateTime_m
public DateTime MyDateTime
{
get
{
using (new ReadLock(rwlMyLock_m))
{
return dtMyDateTime_m;
}
}
set
{
using (new WriteLock(rwlMyLock_m))
{
dtMyDateTime_m = value;
}
}
}
public class ReadLock : IDisposable
{
private ReaderWriterLock rwl;
public ReadLock(ReaderWriterLock rwl)
{
this.rwl = rwl;
rwl.AcquireReaderLock(0);
}
public void Dispose()
{
rwl.ReleaseReaderLock();
}
}
public class WriteLock : IDisposable
{
private ReaderWriterLock rwl;
public WriteLock(ReaderWriterLock rwl)
{
this.rwl = rwl;
rwl.AcquireWriterLock(0);
}
public void Dispose()
{
rwl.ReleaseWriterLock();
}
}发布于 2008-11-10 19:43:02
来自MSDN,using Statement (C# Reference)
using语句可确保即使在调用对象的方法时发生异常,也会调用Dispose。您可以通过将对象放在try块中,然后在finally块中调用Dispose来实现相同的结果;实际上,这就是编译器转换using语句的方式。前面的代码示例在编译时扩展到以下代码(请注意,额外的花括号为对象创建了有限的作用域):
{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}所以基本上,它是相同的代码,但是有一个很好的自动空检查和一个额外的变量作用域。文档还指出,它“确保了IDisposable对象的正确使用”,因此您可能会在将来遇到任何模糊的情况时获得更好的框架支持。
所以使用选项2吧。
将变量放在不再需要它之后立即结束的作用域中也是一个优点。
发布于 2008-11-10 19:36:23
我当然更喜欢第二种方法。它在用法上更简洁,更不容易出错。
在第一种情况下,编辑代码的人必须小心,不要在获取(读|写)Lock调用和try之间插入任何内容。
(不过,在单个属性上使用读/写锁通常有点夸张。它们最好在更高的层次上应用。一个简单的锁在这里通常就足够了,因为考虑到持有锁的时间,争用的可能性可能非常小,并且获取读/写锁比简单的锁更昂贵)。
发布于 2008-11-10 19:52:05
考虑到两种解决方案都不好的可能性,因为它们掩盖了异常。
没有catch的try显然不是一个好主意;有关using语句同样危险的原因,请参阅MSDN。
另请注意,微软现在建议使用ReaderWriterLockSlim而不是ReaderWriterLock。
最后,请注意,微软示例使用了两个try-catch块来避免这些问题,例如
try
{
try
{
//Reader-writer lock stuff
}
finally
{
//Release lock
}
}
catch(Exception ex)
{
//Do something with exception
}一个简单,一致,干净的解决方案是一个很好的目标,但是假设你不能仅仅使用lock(this){return mydateetc;},你可能会重新考虑这种方法;如果有更多的信息,我相信Stack Overflow可以有所帮助;-)
https://stackoverflow.com/questions/278902
复制相似问题