使类的属性线程安全的最佳实践是什么?

Ric*_*ler 8 c# multithreading properties thread-safety c#-4.0

[编辑:看起来原始问题涉及一个double而不是整数.所以我认为这个问题代表我们是否将整数更改为double.]

我很少遇到从多个线程中使用的类读取整数属性,有时会返回零值.初始化后,值不会更改.

这个问题解决了这一点 共识是,即使我正在访问整数,我需要同步属性.(一些原始答案已被删除).我没有在那里选择答案,因为我还没有解决我的问题.

所以我对此做了一些研究,我不确定使用哪个.Net 4的锁定机制,或者锁是否应该在类本身之外.

这是我想到的用法:

  public class ConfigInfo
  {
    private readonly object TimerIntervalLocker = new object();
    private int _TimerInterval;
    public int TimerInterval
    {
      get
      {
        lock (TimerIntervalLocker) {
          return _TimerInterval;
        }
      }
    }

    private int _Factor1;
    public int Factor1
    {
      set
      {
        lock (TimerIntervalLocker) {
          _Factor1 = value;
          _TimerInterval = _Factor1 * _Factor2;
        }
      }
      get
      {
        lock (TimerIntervalLocker) {
          return _Factor1;
        }
      }
    }

    private int _Factor2;
    public int Factor2
    {
      set
      {
        lock (TimerIntervalLocker) {
          _Factor2 = value;
          _TimerInterval = _Factor1 * _Factor2;
        }
      }
      get
      {
        lock (TimerIntervalLocker) {
          return _Factor2;
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

但我读过这个速度非常慢.

另一种方法是锁定ConfigData用户端的实例,但这似乎是很多工作.我见过的另一种选择是Monitor.Enter,Monitor.Exit但我认为Lock与语法较少是一回事.

那么什么是使类的属性线程安全的最佳实践?

Dan*_*rod 1

A。使用锁可能会很慢,因为它使用操作系统资源,如果属性的复杂性较低,那么自旋锁(或 interlocked.compareexchange)会更快。

b. 您必须确保线程不会进入锁并通过从一个属性到另一个属性的调用而被锁定。- 如果发生这种情况(当前这不是代码中的问题),则需要使锁定线程或任务敏感。

编辑:

如果该对象应该在初始化期间设置并且从未更改,请使其不可变(就像 .NET 字符串一样)。删除所有公共 setter 并提供一个带有用于定义初始状态的参数的构造函数,以及用于创建具有修改状态的新实例的附加方法/运算符(例如 var newString = "Old string" + " was generated.";)。