C# Неизменность создания глобального магазина
Для моего проекта я пытаюсь создать единое глобальное хранилище для обслуживания изменяемого состояния, например:
// 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);
});
}
Вопросы:
Этот поток кода безопасен? в частности, мне нужно заблокировать геттер Store.State? мои рассуждения таковы, что получатель выполняет атомарное присваивание, копируя ссылку на состояние по значению, тогда мне не нужно его здесь блокировать?
Могу ли я / я использовать ImmutableInterlocked здесь?
1 ответ
Этот поток кода безопасен? в частности, мне нужно заблокировать геттер Store.State? Мое рассуждение таково: поскольку получатель выполняет атомарное присваивание, копируя ссылку на состояние по значению, тогда мне не нужно его здесь блокировать?
Пока вы довольны устаревшими данными, да, они будут работать нормально.
Могу ли я / я использовать ImmutableInterlocked здесь?
Да, я думаю, что вы должны (но вы должны зарегистрироваться, чтобы подтвердить, действительно ли это дает выгоду). ImmutableInterlocked.Update
это то, что я бы предложил.