代码之家  ›  专栏  ›  技术社区  ›  kofifus

c#不变性创建全局存储

  •  0
  • kofifus  · 技术社区  · 6 年前

      // Immutable program state
      sealed public class State : IEquatable<State> {
        public State(ClientsConnections clientsConnections, ImmutableList<string> ids) {
          this.ClientsConnections = clientsConnections;
          this.Ids = ids;
        }
    
        public readonly ClientsConnections ClientsConnections; // ClientsConnections is immutable
        public readonly ImmutableList<string> Ids; // also immutable
    
        public override int GetHashCode() => HashCode.Combine(AgentsConnections.GetHashCode(), Ids.GetHashCode());
        public override bool Equals(object obj) { var o = obj as State; return o is null ? false : ClientsConnections.Equals(o.ClientsConnections) && Ids.Equals(Ids); }
        public bool Equals(State o) => object.Equals(this, o); 
        public static bool operator ==(State o1, State o2) => object.Equals(o1, o2); 
        public static bool operator !=(State o1, State o2) => !object.Equals(o1, o2);
      }
    
      // Store is a mutable singleton
      sealed public class Store {
        readonly object stateLock = new object();
    
        public Store() => this.State = new State(new ClientsConnections(), ImmutableList<string>.Empty);
    
        public State State { get; private set; }
        public void SetState(Func<State, State> f) { lock (stateLock) State = f(State); }
      }
    

    然后我在代码中这样使用它:

    Thread1 - f1() { 
      var currState=Store.State; 
      log(currState.ids);
    }
    
    Thread2 - f2() { 
      Store.SetState(currState => {
        var newids = currState.Ids.Add("hello");
        return new State(currState.ClientsConnections, newids);
      });
    }
    

    问题:

    1. 这个代码是线程安全的吗?尤其是我需要锁上商店吗?州政府官员?我的理由是,由于getter做了一个按值复制状态引用的原子赋值,所以我不需要将其锁定在这里?

    2. 我可以/应该在这里使用不可变的联锁吗?

    1 回复  |  直到 6 年前
        1
  •  0
  •   mjwills Myles McDonnell    6 年前

    这个代码是线程安全的吗?尤其是我需要锁上 商店。州政府官员?我的理由是因为吸气剂是原子的 把它锁在这里?

    只要你对陈旧的数据感到满意,是的,它会工作得很好。

    我可以/应该在这里使用不可变的联锁吗?

    ImmutableInterlocked.Update 是我的建议。