序列化对象引发System.OutOfMemoryException异常

5

我在使用“JsonConvert.SerializeObject”时遇到了严重的问题。我需要将500,000多个字典记录进行序列化,但是序列化会抛出以下错误:System.OutOfMemoryException。我尝试在foreach中分别对每个键值对进行序列化,但是代码被锁住了。显然这是一个优化问题,但是我不知道从哪里开始,是否可以采用线程分批次进行序列化?

这些函数在处理少量数据时运行良好。

我的代码:

string json = JsonConvert.SerializeObject(DatatableToDictionary(dt), Newtonsoft.Json.Formatting.Indented);

public List<Dictionary<string, object>> DatatableToDictionary(DataTable dt, List<DataColumn> columns)
{
    return dt.Rows.Cast<DataRow>().Select(
         r => columns.ToDictionary(c => c.ColumnName, c => r[c.ColumnName])).ToList();
}

也许你需要恢复到 JsonWriter - Lasse V. Karlsen
罪魁祸首可能是循环引用。 - Don Cheadle
1
很可能要创建的JSON字符串总大小太大了。你能展示一下你的字典结构和周围类型吗?我能够使用流、StreamWriter和JsonTextWriter轻松快速地将一百万个字典键和值写入JSON文件。 - Lasse V. Karlsen
请问如何恢复jsonWriter并知道是否存在循环引用? - gvivetapl
1个回答

5

当您处理大量数据时,可以将其流式传输到文件中,以避免一次性在内存中保存所有数据。

var filePath = @"C:\somewhere.json";

using (var fs = File.Open(filePath, FileMode.CreateNew))
using (var sw = new StreamWriter(fs))
using (var jw = new JsonTextWriter(sw))
{
    var serializer = new JsonSerializer();
    serializer.Serialize(jw, dictionary);
}

这将逐位串行化并避免在内存中产生巨大的字符串。

是的,它运行良好。我猜我必须读取文件以检索数据?因为它是一个Web API,就像我为MVC应用程序所做的那样。有没有办法将信息存储在缓存中而不是任何路径中? - gvivetapl
是的,然后您可以读取文件以获取数据。读取它基本上是相反的过程。该文件基本上可以充当缓存。 - mason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接