实现了BeginUpdate和EndUpdate

本文关键字:EndUpdate BeginUpdate 实现 | 更新日期: 2023-09-27 18:12:15

1)我正在做一个项目,我看到了这段代码,我不明白监视器的意义是什么。锁的声明。有人能解释一下它想做什么吗?

2)参数名中的后记非常烦人,还有人见过这种命名约定吗?

public class FieldsChangeableHelper<T> : IFieldsChangeable<T>
{
    object _lock;
    int _lockCount;
    FieldChanges<T> _changes;
    public FieldsChangeableHelper()
    {
        _lock = new object();
        _lockCount = 0;
    }
    public void AddChange(T field_, object oldValue_)
    {
        if (_changes == null)
            _changes = new FieldChanges<T>(field_, oldValue_);
        else
            _changes.AddChange(field_, oldValue_);
        if (RaiseEvent(_changes))
            _changes = null;
    }
    #region IFieldsChangeable Members
    public void BeginUpdate()
    {
        if (System.Threading.Interlocked.Increment(ref _lockCount) == 1)
            Monitor.Enter(_lock);
    }
    public void EndUpdate()
    {
        if (System.Threading.Interlocked.Decrement(ref _lockCount) == 0)
        {
            FieldChanges<T> changes = _changes;
            _changes = null;
            Monitor.Exit(_lock);
            RaiseEvent(changes);
        }
    }

    protected bool RaiseEvent(FieldChanges<T> changes_)
    {
        if (_lockCount == 0 && Changed != null && changes_ != null)
        {
            Changed(this, changes_);
            return true;
        }
        return false;
    }
    public event FieldsChanged<T> Changed;
    #endregion
}

实现了BeginUpdate和EndUpdate

监控。当多个线程试图并行执行同一段代码时,Lock锁定该代码部分。这样做是为了确保只有一个人在修改/执行上下文。看MSDN

虽然锁定对象始终是静态的是最佳实践,但在您的情况下它不是。如果在一个开放类型上实例化多个对象,这可能会造成一些问题。

注意一件事,在泛型中,打开T上的静态对于不同的类型是不同的,也就是说,在你的例子中,打开类型类中的静态成员对于T是不同的,例如DateTime, string等。

在csharp中,类型的私有成员通常以前缀_

命名。

我读它的方式:BeginUpdate()确保当前线程调用具有对实例的独占访问权,并且一旦调用EndUpdate,更改事件实际上将被批处理并引发。作者希望自己处理递归(例如在同一线程上多次调用BeginUpdate())和一种批量UpdateEvents的机制,直到锁被释放之后。因为,当您仍然对自己有锁时,在引发事件时可能会出现死锁。事件订阅者可能想要访问您的成员,因此必须锁定已经锁定的发送方实例。

整个条件锁定是不需要的(如果我的分析当然是正确的),因为基于Monitor类的锁是递归的和计数的。

锁机制还有另一个问题,那就是:当前当一个线程持有锁时。第二个线程甚至不会等待锁,而只是在没有锁的情况下继续,因为锁是有条件的!这看起来像个大虫子!

关于命名约定。我自己用它来区分私变量与参数和局部变量。这是许多c#编码约定推荐的首选项。这在以下情况下很有帮助:

void Method(int number)
{
    // no need to refer to this since:
    //this.number = number; 
    // can be replaced with
    _number = number;
}