Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何序列化具有不断更新集合的对象_C#_Serialization_Collections - Fatal编程技术网

C# 如何序列化具有不断更新集合的对象

C# 如何序列化具有不断更新集合的对象,c#,serialization,collections,C#,Serialization,Collections,我有一个缓存服务,它保存多个Price对象,这些对象会随着新的Price delta的到来而更新,有时一秒钟会更新多次。 每个对象在一个分配给ID的集合中保存它的各种价格。如果有人订阅某个特定的价格,我需要在每次新价格到达时将最新的价格对象序列化为JSON,以便通过RMQ发送。我遇到的问题是,在某些情况下,我在序列化时收到以下错误消息,因为新的价格已经到达,并且在前一个版本的序列化过程中更新了对象上的集合 “集合已修改;枚举操作可能无法执行。” 我尝试了各种序列化对象的方法(它需要尽可能快),但

我有一个缓存服务,它保存多个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。