I need to update InstrumentInfo
class frequently. I update this class from one thread and access (read) from another.
I have Instrument
class. For each Instrument
class I need to maintain 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
I do have two options:
- Create only one
InstrumentInfo
for eachInstrument
. When some field updates, for exampleBestBuy
just update value of this field. Clients should obtainInstrumentInfo
only once and use it during entire application lifetime. - On each update create new instance of
InstrumentInfo
. Clients should obtain every time the most recent copy of InstrumentInfo.
With 1
I do need to lock, because decimal
DateTime
string
update is not guaranteed to be atomic. But I don't need to reinstatiate object.
With 2
I don't need to lock at all, as reference
update is atomic. But I likely will use more memory and I will probably create more work for GC because every time I need to instatiate new object (and initialize all fields).
1
implementation
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
implementation:
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
So what do you think? I want to use approach 2
because I like code without locks! Am I correct that I do not need lock
at all as I just replace reference? Do you aggree that 2
is preferred? Any suggestions are welcome.