C#Compact Framework-具有XmlSerializer.Serialize的OutOfMemoryException [英] C# Compact Framework - OutOfMemoryException with XmlSerializer.Serialize

查看:106
本文介绍了C#Compact Framework-具有XmlSerializer.Serialize的OutOfMemoryException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试序列化集合中的大量对象(20,000)个对象.我正在使用以下代码进行此操作:

I'm trying to serialize a large collection of objects (20,000) objects within the collection. I'm doing this using the following code:

XmlSerializer xs = new XmlSerializer(deserialized.GetType());
StringWriter sw;
using (sw = new StringWriter())
{
   xs.Serialize(sw, deserialized);   // OutOfMemoryException here
}

string packet = sw.ToString();
return packet;

是否有更好的方法来执行此操作,或者我做的是公然错误的事情?

Is there a better way of doing this, or am I doing something blatantly wrong?

推荐答案

应该看起来可行,但是CF确实有不可预测的局限性.

It looks like it should work, but CF does have unpredictable limitations.

是否需要xml?我不记得要尝试处理2万条记录,但是另一种选择可能是使用其他序列化器 try -例如,

Is xml a requirement? I can't remember trying it with 20k records, but another option might be to try using a different serializer - for example, protobuf-net works on CF2. I can't guarantee it'll work, but it might be worth a shot.

(特别是,我目前正在重构代码,以尝试解决其他一些泛型"限制-但除非您有非常复杂的对象模型,否则这不会影响您).

(in particular, I'm currently refactoring the code to try to work around some additional "generics" limitations within CF - but unless you have a very complex object model this shouldn't affect you).

示例显示用法;请注意,此示例对于XmlSerializer也可以正常工作,但是protobuf-net仅使用20%的空间(如果您认为字符在内存中每个为两个字节,则使用10%的空间):

Example showing usage; note that this example also works OK for XmlSerializer, but protobuf-net uses only 20% of the space (or 10% of the space if you consider that characters are two bytes each in memory):

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

[Serializable, ProtoContract]
public class Department
{
    [ProtoMember(1)]
    public string Name { get; set; }
    [ProtoMember(2)]
    public List<Person> People { get; set; }
}

[Serializable, ProtoContract]
public class Person
{
    [ProtoMember(1)]
    public int Id { get; set; }
    [ProtoMember(2)]
    public string Name { get; set; }
    [ProtoMember(3)]
    public DateTime DateOfBirth { get; set; }
}


static class Program
{
    [MTAThread]
    static void Main()
    {
        Department dept = new Department { Name = "foo"};
        dept.People = new List<Person>();
        Random rand = new Random(123456);
        for (int i = 0; i < 20000; i++)
        {
            Person person = new Person();
            person.Id = rand.Next(50000);
            person.DateOfBirth = DateTime.Today.AddDays(-rand.Next(2000));
            person.Name = "fixed name";
            dept.People.Add(person);
        }

        byte[] raw;
        using (MemoryStream ms = new MemoryStream())
        {
            Serializer.Serialize(ms, dept);
            raw = ms.ToArray(); // 473,399 bytes
        }

        XmlSerializer ser = new XmlSerializer(typeof(Department));
        StringWriter sw = new StringWriter();
        ser.Serialize(sw, dept);
        string s = sw.ToString(); // 2,115,693 characters
    }
}

如果您需要更多帮助,请告诉我-我可以整天谈论这个主题;-p 请注意,它只能从标准xml属性([XmlElement(Order=1)])开始工作-为了清楚起见,我使用了更具体的[ProtoMember(1)]等.这也允许对序列化进行细粒度的控制(Zigzag与twoscompliment,分组vs与长度前缀等).

Let me know if you want more help - I can talk about this subject all day ;-p Note that it can work just from the standard xml attributes ([XmlElement(Order=1)]) - I've used the more specific [ProtoMember(1)] etc for clarity. This also allows fine-grained control of serialization (zigzag vs twoscompliment, grouped vs length-prefixed, etc).

这篇关于C#Compact Framework-具有XmlSerializer.Serialize的OutOfMemoryException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆