C# 如何更新频繁更改的类?每次恢复还是只更新字段?
我需要经常更新C# 如何更新频繁更改的类?每次恢复还是只更新字段?,c#,C#,我需要经常更新InstrumentInfo类。我从一个线程更新这个类,并从另一个线程访问(读取) 我有仪器课。对于每个仪器类别,我需要维护仪器信息: // omit class Instrument as not improtant public class InstrumentInfo { public string Name { get; set; } public TradingStatus Status { get; set; } public decimal
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
我有两个选择:
仪器
只创建一个仪器信息
。当某些字段更新时,例如百思买
只需更新此字段的值。客户端应仅获取一次InstrumentInfo
,并在整个应用程序生命周期内使用它InstrumentInfo
的新实例。客户每次都应获取InstrumentInfo的最新副本1
我确实需要锁定,因为十进制
日期时间
字符串
更新不保证是原子的。但我不需要恢复这个物体
使用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
那你觉得呢?我想使用approach2
,因为我喜欢没有锁的代码!我完全不需要锁
,因为我只是替换了引用,对吗?您是否同意首选2
?欢迎提出任何建议
使用2
我根本不需要锁定,因为引用更新是原子的。但是我可能会使用更多的内存,我可能会为GC创建更多的工作,因为
不,您的选项1
同样可能导致GC上的负载增加(通过将更多对象升级到下一代)
2
我根本不需要锁定,因为引用更新是原子的。但是我可能会使用更多的内存,我可能会为GC创建更多的工作,因为
不,您的选项1
同样可能导致GC上的负载增加(通过将更多对象升级到下一代)
你应该考虑几个无关的问题。
- 应变记忆
- 被认为是“反OOP”
- 可能被客户端代码错误地使用(因为人们不习惯与他们一起工作)
联锁的.Exchange
?感谢亨克·霍特曼指出这一点你应该考虑几个无关的问题。
- 应变记忆
- 被认为是“反OOP”
- 可能被客户端代码错误地使用(因为人们不习惯与他们一起工作)
联锁的.Exchange
?感谢亨克·霍特曼指出这一点为了以防万一,锁定一个
私有静态只读对象
,而不是仪器信息数组-就像防御性的编码实践一样。@codesparkle-锁定一个静态
对象会导致(更多)争用。当前的方法(ii
不是数组)看起来还可以。@Henkholtman他正在锁定lock(instrumentInfos){
这是一个数组。ii
与它无关。但是你是对的,使它静态是不必要的,也是不好的。只读可以。你是对的,我正在查看另一个锁。锁(仪表信息)
可能根本不需要。@HenkHolterman需要保证只创建了一个实例。如果从不同的线程调用GetInstrumentInfo,一个线程可能会获得无效的副本。当然,代码可能会被重构,所以我只在结果==null
的情况下锁定private静态只读对象
而不在您的仪表信息数组中-这只是一种防御性的编码实践。@codesparkle-锁定静态
对象将导致(远远)超出必要的争用。当前的方法(ii
不是数组)看起来还可以。@Henkhoterman他正在锁定锁(仪表信息){
这是一个数组。ii
与此无关。但是你是对的,将其设为静态是不必要的,也是不好的。只读即可。你是对的,我正在查看另一个锁。锁(instrumentInfos)
可能根本不需要。@HenkHolterman需要保证只创建了一个实例。如果从不同的线程调用GetInstrumentInfo,一个线程可能会获得无效的副本。当然,代码可能会被重构,因此只有在