在序列化需要作为JSON移植到DataTable的对象列表时运行到OutOfMemoryException

时间:2016-04-08 20:11:18

标签: c# asp.net json datatable

我有一个非常大的对象列表(总计186799),我试图以JSON格式移植到DataTable。序列化对象列表的总长度为62553299.如何将此数据从JSON格式的Web服务移植到aspx文件中的DataTable。

public void GetData()
{
    DataTable dt;
    string connectionString = "----";
    string selectCommand = "SELECT -----";
    using (AdomdConnection conn = new AdomdConnection(connectionString))
    {
        conn.Open();
        using (AdomdDataAdapter adapter = new AdomdDataAdapter (selectCommand, conn))
        {
            dt = new DataTable();
            adapter.Fill(dt);
            List<ResourceData> ResourceInfo = new List<ResourceData>();
            ResourceData ResourceInfoRow = null;
            foreach (DataRow dr in dt.Rows)
            {
                ResourceInfoRow = new ResourceData();
                ResourceInfoRow.SourceProject = dr.ItemArray[0].ToString();
                ResourceInfoRow.SourceFile= dr.ItemArray[1].ToString();
                ResourceInfoRow.Project = dr.ItemArray[2].ToString();
                ResourceInfoRow.File = dr.ItemArray[3].ToString();
                ResourceInfoRow.Parent = dr.ItemArray[4].ToString();
                ResourceInfoRow.Id = dr.ItemArray[5].ToString();
                ResourceInfo.Add(ResourceInfoRow);
            }
            JavaScriptSerializer js = new JavaScriptSerializer();
            js.MaxJsonLength = 2147483647;
            Context.Response.Write(js.Serialize(ResourceInfo)); //This is where I hit the OutOfMemoryException
        }
        conn.Close();
    }
}

我必须以json格式移植数据,因为我使用的是DataTable插件。

感谢您的回复。

2 个答案:

答案 0 :(得分:1)

很可能你的字符串对于你的记忆来说很大,或者它自己的字符串很大(2gb)。您尝试序列化很多对象。因此,最好的方法是将对象拆分为多个卡盘以进行序列化。或者您可以尝试其他转换器,例如:Newtonsoft。 Newtonsoft串行器是一个快速且可能是最常用的串行器。 Newtonsoft序列化程序也可以使用流转换为json:Serialize to stream。哪个可以直接写入Response对象。

答案 1 :(得分:0)

简而言之,JavascriptSerializer具有多个重载。如果您使用返回字符串的字符串,则将限于StringBuilder max .ToString()容量刚好超过100.000.000个字符(.net中的字符串长度限制)。

    //.Net source
    internal string Serialize(object obj, SerializationFormat serializationFormat)
    {
        StringBuilder sb = new StringBuilder();
        Serialize(obj, sb, serializationFormat);
        return sb.ToString();
    }

因此,请在提供StringBuilder的地方使用重载。然后,在序列化之后,一次使用.ToString(index,length)最多不超过100.000.000个字符的最大大小来获取字符串大块。

    public void Serialize(object obj, StringBuilder output)
    {
        Serialize(obj, output, SerializationFormat.JSON);
    }

    //usage afterwards
    sb.ToString(0, 100000);

请参见StringBuilder.ToString() throws OutOfMemoryException