c# – 微软对ReaderWriterLockSlim.IsReadLockHeld / IsWriteLockHeld的评论及其后果

前端之家收集整理的这篇文章主要介绍了c# – 微软对ReaderWriterLockSlim.IsReadLockHeld / IsWriteLockHeld的评论及其后果前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
要同步对我的属性的访问,我使用 ReaderWriterLockSlim类.我使用以下代码以线程安全的方式访问我的属性.
public class SomeClass
{
    public readonly ReaderWriterLockSlim SyncObj = new ReaderWriterLockSlim();  
    public string AProperty
    {
        get
        {
            if (SyncObj.IsReadLockHeld)
                return ComplexGetterMethod();
            SyncObj.EnterReadLock();
            try
            {
                return ComplexGetterMethod();
            }
            finally
            {
                SyncObj.ExitReadLock();
            }
        }
        set
        {
            if (SyncObj.IsWriteLockHeld)
                ComplexSetterMethod(value);
            else
            {
                SyncObj.EnterWriteLock();
                ComplexSetterMethod(value);
                SyncObj.ExitWriteLock();
            }
        }
    }

    // more properties here ...

    private string ComplexGetterMethod()
    {
        // This method is not thread-safe and reads
        // multiple values,calculates stuff,ect. 
    }

    private void ComplexSetterMethod(string newValue)    
    {
        // This method is not thread-safe and reads
        // and writes multiple values.
    }
}

// =====================================

public static SomeClass AClass = new SomeClass();
public void SomeMultiThreadFunction()
{
    ...
    // access with locking from within the setter
    AClass.AProperty = "new value";
    ...
    // locking from outside of the class to increase performance
    AClass.SyncObj.EnterWriteLock();
    AClass.AProperty = "new value 2";
    AClass.AnotherProperty = "...";
    ...
    AClass.SyncObj.ExitWriteLock();
    ...
}

每当我收到或设置多个属性时,为了避免不必要的锁定,一旦我发布了ReaderWriterLockSlim-Object,并且每当我要获取或设置一堆属性时,它会从类外部锁定.为了达到这个目的,我的getter和setter方法检查是否已经使用IsReadLockHeld属性和ReaderWriterLockSlim的IsWriteLockHeld属性获取锁.这工作正常,并增加了我的代码性能.@H_301_5@

到目前为止这么好,但是当我重新阅读有关IsReadLockHeld和IsWriteLockHeld的文档时,我注意到Microsoft的备注:@H_301_5@

This property is intended for use in asserts or for other debugging
purposes. Do not use it to control the flow of program execution.@H_301_5@

我的问题是:为什么我不应该使用IsReadLockHeld / IsWriteLockHeld为此目的?我的代码有什么问题吗?一切都按预期方式工作,比使用递归锁(LockRecursionPolicy.SupportsRecursion)快得多.@H_301_5@

澄清一下:这是一个最小的例子.我不想知道锁本身是否必要或可以以不同的方式被删除或实现.我只是想知道为什么我不应该使用IsReadLockHeld / IsWriteLockHeld来控制程序的流程,如文档所述.@H_301_5@

解决方法

经过进一步研究,我在 German Support Forum of the Microsoft Developer Network发表了同样的问题,并与非常有帮助的主持人马塞尔·罗姆(Marcel Roma)进行了讨论.他能够联系写作这个答案的ReaderWriterLockSlim Joe Duffy的程序员:

I’m afraid my answer may leave something to be desired.@H_301_5@

The property works fine and as documented. The guidance really is just
because conditional acquisition and release of locks tends to be buggy
and error-prone in practice,particularly with exceptions thrown into
the mix.@H_301_5@

It’s typically a good idea to structure your code so that you either
use recursive acquires,or you don’t,(and of course the latter is
always easier to reason about); using properties like IsReadLockHeld
lands you somewhere in the middle.@H_301_5@

I was one of the primary designers of RWLS and I have to admit it has
way too many bells and whistles. I don’t necessarily regret adding
IsReadLockHeld — as it can come in handy for debugging and assertions
— however as soon as we added it,Pandora’s Box was opened,and we RWLS was instantly opened up to this kind of usage.@H_301_5@

I’m not surprised that people want to use it as shown in the
StackOverflow thread,and I’m sure there are some legitimate scenarios
where it works better than the alternatives. I merely advise erring on
the side of not using it.@H_301_5@

总结一下:您可以使用IsReadLockHeld和IsWriteLockHeld属性来有条件地获取锁定,一切都可以正常工作,但是编程风格不好,应避免使用.最好坚持递归或非递归锁.为了保持良好的编码风格,IsReadLockHeld和IsWriteLockHeld只能用于调试目的.@H_301_5@

我要再次感谢马塞尔·罗马和乔·达菲的宝贵帮助.@H_301_5@

猜你在找的C#相关文章