C# 如何序列化具有不断更新集合的对象
我有一个缓存服务,它保存多个Price对象,这些对象会随着新的Price delta的到来而更新,有时一秒钟会更新多次。 每个对象在一个分配给ID的集合中保存它的各种价格。如果有人订阅某个特定的价格,我需要在每次新价格到达时将最新的价格对象序列化为JSON,以便通过RMQ发送。我遇到的问题是,在某些情况下,我在序列化时收到以下错误消息,因为新的价格已经到达,并且在前一个版本的序列化过程中更新了对象上的集合 “集合已修改;枚举操作可能无法执行。” 我尝试了各种序列化对象的方法(它需要尽可能快),但我仍然遇到同样的问题 解决这个问题的最佳和最有效的方法是什么,这样即使对象发生变化,我也可以序列化 简化对象包括:C# 如何序列化具有不断更新集合的对象,c#,serialization,collections,C#,Serialization,Collections,我有一个缓存服务,它保存多个Price对象,这些对象会随着新的Price delta的到来而更新,有时一秒钟会更新多次。 每个对象在一个分配给ID的集合中保存它的各种价格。如果有人订阅某个特定的价格,我需要在每次新价格到达时将最新的价格对象序列化为JSON,以便通过RMQ发送。我遇到的问题是,在某些情况下,我在序列化时收到以下错误消息,因为新的价格已经到达,并且在前一个版本的序列化过程中更新了对象上的集合 “集合已修改;枚举操作可能无法执行。” 我尝试了各种序列化对象的方法(它需要尽可能快),但
//This is the collection on an object that holds the prices which are being updated
public ConcurrentDictionary<Id, Prices> Asset{ get; set; }
//Class that holds the ever updating prices
[Serializable]
public class Prices
{
public Prices()
{
Prices1 = new List<PriceVolume>();
Prices2 = new List<PriceVolume>();
}
}
//这是保存正在更新的价格的对象上的集合
公共ConcurrentDictionary资产{get;set;}
//类,该类保存不断更新的价格
[可序列化]
公共类价格
{
公共价格()
{
价格1=新列表();
价格2=新列表();
}
}
提前谢谢 不应该序列化从并发字典中提取的实际对象,而应该创建它的深度副本并序列化副本。不幸的是,您仍然需要将代码放入互斥锁中才能获得副本。ConcurrentDic仅保护您在检索项目时不被更改或删除,检索到对对象的引用后,它不会保护对象不被操纵。与其序列化从并发字典中提取的实际对象,不如创建该对象的深度副本并序列化副本。不幸的是,您仍然需要将代码放入互斥锁中才能获得副本。ConcurrentDic只保护您在检索项目时不被更改或删除,它不保护对象在检索到对它的引用后不被操纵。在序列化该元素时,您可能会从中受益 锁定可防止其他线程在您处于锁内时修改图元 这将使试图更改价格的操作等待您完成序列化以修改价格
[Serializable]
public class Prices
{
public string Serialize()
{
lock (this)
{
// logic for serilization here
}
}
}
在序列化元素时,您可能会从中受益 锁定可防止其他线程在您处于锁内时修改图元 这将使试图更改价格的操作等待您完成序列化以修改价格
[Serializable]
public class Prices
{
public string Serialize()
{
lock (this)
{
// logic for serilization here
}
}
}
只是一个想法,但是看看序列化回调(有些人将其称为序列化挂钩)并实现ISerializable接口怎么样。您似乎需要对对象的序列化进行更细粒度的控制。请查看此链接: 看看下面的例子
- OnDeserializengAttribute(反序列化之前)
- OnDeserializedAttribute(反序列化后)
- 序列化属性(序列化前)
- OnSerializedAttribute(序列化后)
您可以考虑对象是否保证在某些字段上使用“强> opopalFieldPosits <强> >或<强>非序列化属性< /强>,以控制它们是否需要序列化或可选序列化。只需小心使用非序列化数据属性。看一看文章中提到的最佳实践(此处转载供参考):
为了确保正确的版本控制行为,在不同版本之间修改类型时,请遵循以下规则:- 永远不要删除序列化字段
- 如果在以前的版本中属性未应用于字段,则切勿将NonSerializedAttribute属性应用于该字段
- 切勿更改序列化字段的名称或类型
- 添加新的序列化字段时,应用OptionalFieldAttribute属性
- 从字段中删除NonSerializedAttribute属性(在以前的版本中不可序列化)时,应用OptionalFieldAttribute属性
- 对于所有可选字段,使用序列化回调设置有意义的默认值,除非可以接受0或null作为默认值
- 始终正确设置OptionalFieldAttribute属性上的VersionAdded属性
- 避免分支版本控制
只是一个想法,但是看看序列化回调(有些人将其称为序列化挂钩)并实现ISerializable接口怎么样。您似乎需要对对象的序列化进行更细粒度的控制。请查看此链接: 看看下面的例子
- OnDeserializengAttribute(反序列化之前)
- OnDeserializedAttribute(反序列化后)
- 序列化属性(序列化前)
- OnSerializedAttribute(序列化后)
您可以考虑对象是否保证在某些字段中使用“强> opopalFieldPosits <强> >或<强>非序列化属性< /强>来控制它们是否需要序列化或optA。