【问题标题】:BlockingCollection default accessorBlockingCollection 默认访问器
【发布时间】:2016-01-12 03:29:56
【问题描述】:

我正在使用 BlockingCollection,但在尝试对其进行序列化时遇到了问题。错误发生在 new XmlSerializer 行上。错误是:

您必须在 System.Collections.Concurrent.BlockingCollection`1[[BlockingCollTest.MyItem, BlockingCollTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] 上实现默认访问器,因为它继承自 ICollection。

测试程序是:

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace BlockingCollTest
{
    class Program
    {
        static void Main(string[] args)
        {
            BlockingCollection<MyItem> c = new BlockingCollection<MyItem>();
            c.Add(new MyItem("001", "Smith"));
            c.Add(new MyItem("002", "Johnson"));

            XmlSerializer serializer = new XmlSerializer(typeof(BlockingCollection<MyItem>));
        }
    }
    [Serializable]
    public class MyItem
    {
        public string ID { get; set; }
        public string Name { get; set; }
        public MyItem() { }
        public MyItem(string id, string name) { ID = id; Name = name; }
    }
}

在尝试了几种解决方案后,我不知道如何解决此错误。

问题:解决 BlockingCollection 问题的序列化需要什么?

【问题讨论】:

  • 序列化一个旨在作为线程安全集合的类是非常值得怀疑的。一种解决方法是使用其 ToArray() 方法并序列化数组。

标签: c# concurrent-collections


【解决方案1】:

BlockingCollection 不属于 [Serializable] 并且不实现 ISerializable。因此,即使 MyItem 是可序列化的,您也无法使用 XmlSerializer 对其进行序列化。您可以将项目复制到单个可序列化集合或数组(例如 MyItem[]),对其进行序列化并在反序列化后重新创建 BlockingCollection。

【讨论】:

  • 谢谢你。我没有发现 BlockingCollection 不可序列化。你的解决方案很有意义。
  • 感谢 Hans,他在评论中给出了正确的答案。提交我的答案后才看到它(对不起)
  • ConcurrentQueue(使用默认构造函数时用作基础集合的集合)是可序列化的。如果您使用this constructor 并保留对队列的引用,则可以对队列进行序列化,然后在反序列化时构建一个新的BlockingCollection,将序列化队列传入。可能比使用数组更好。
猜你喜欢
  • 2010-10-12
  • 1970-01-01
  • 2022-12-24
  • 1970-01-01
  • 2015-10-06
  • 2014-04-09
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
相关资源
最近更新 更多