InstrumentInfo
クラスを頻繁に更新する必要があります。あるスレッドからこのクラスを更新し、別のスレッドからアクセス (読み取り) します。
Instrument
クラスがあります。Instrument
私が維持する必要がある各クラスについてInstrumentInfo
:
// omit class Instrument as not improtant
public class InstrumentInfo
{
public string Name { get; set; }
public TradingStatus Status { get; set; }
public decimal MinStep;
public double ValToday;
public decimal BestBuy;
public decimal BestSell;
}
public class DerivativeInfo : InstrumentInfo
{
public DateTime LastTradeDate { get; set; }
public DateTime ExpirationDate { get; set; }
public string UnderlyingTicker { get; set; }
}
// i do have several more subclasses
2 つのオプションがあります。
InstrumentInfo
ごとに1 つだけ作成しますInstrument
。一部のフィールドが更新されると、たとえばBestBuy
、このフィールドの値が更新されます。クライアントはInstrumentInfo
一度だけ取得し、アプリケーションの存続期間全体で使用する必要があります。- 更新ごとに、 の新しいインスタンスを作成します
InstrumentInfo
。クライアントは、InstrumentInfo の最新のコピーを毎回取得する必要があります。
更新がアトミックであることが保証されていない1
ため、ロックする必要があります。decimal
DateTime
string
しかし、オブジェクトを元に戻す必要はありません。
更新はアトミックで2
あるため、ロックする必要はまったくありません。reference
しかし、新しいオブジェクトを開始する (そしてすべてのフィールドを初期化する) 必要があるたびに、より多くのメモリを使用する可能性が高く、おそらく GC のためにより多くの作業を作成することになります。
1
実装
private InstrumentInfo[] instrumentInfos = new InstrumentInfo[Constants.MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
// invoked from different threads
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
lock (instrumentInfos) {
var result = instrumentInfos[instrument.Id];
if (result == null) {
result = new InstrumentInfo();
instrumentInfos[instrument.Id] = result;
}
return result;
}
}
...........
InstrumentInfo ii = GetInstrumentInfo(instrument);
lock (ii) {
ii.BestSell = BestSell;
}
2
実装:
private InstrumentInfo[] instrumentInfos = new InstrumentInfo[Constants.MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
// get and set are invoked from different threads
// but i don't need to lock at all!!! as reference update is atomic
public void SetInstrumentInfo(Instrument instrument, InstrumentInfo info)
{
if (instrument == null || info == null)
{
return;
}
instrumentInfos[instrument.Id] = info;
}
// get and set are invoked from different threads
public InstrumentInfo GetInstrumentInfo(Instrument instrument)
{
return instrumentInfos[instrument.Id];
}
....
InstrumentInfo ii = new InstrumentInfo {
Name = ..
TradingStatus = ...
...
BestSell =
}
SetInstrumentInfo(instrument, ii); // replace InstrumentInfo
それで、あなたはどう思いますか?2
ロックのないコードが好きなのでアプローチしたい!lock
参照を置き換えるだけなので、まったく必要ないというのは正しいですか?2
それが好ましいことに同意しますか?どんな提案でも大歓迎です。