这是我的情况 - 我有一个简单的对象模型。在根目录,有一个Report对象。报告有一系列文档。每个文档都有一个章节和页面数组。这些对象中的每一个都有4或5个属性(基元 - 字符串和整数)。它看起来像这样:
很简单,对吧?
这是我的问题。在长时间运行的进程完成后,我有一个报表对象,通常有大约5000个Document对象。每个文档大约有200个章节对象和200个页面对象。
换句话说,Report对象的内存占用量相当大。 5,000份文件,1,00,000章和1,000,000页。如果我将对象序列化为内存流,它可以大到80MB。
问题是我必须通过线路移动这个对象(是的,这是必须的)。
这就是我需要帮助的地方!
我的第一次尝试只是尝试使用标准WCF服务移动整个对象,其中对象模型使用DataContract / DataMember属性进行修饰。给定图中对象的数量以及序列化对象的总体大小(因为WCF正在创建XML),这是不可行的。即使将 maxReceivedMessageSize 和 maxItemsInObjectGraph 设置为最高可能值,也无法完成工作。另外,这是一个缓冲请求,这似乎不是一个好主意。
我的第二次尝试是使用 System.ServiceModel.Channels.Message 实例创建WCF StreamedRequest。这似乎有助于在没有任何问题的情况下通过线路获取大型Report对象。请求是流式传输的,因此传输不是问题。但问题是,当WCF服务收到对象时,我需要反序列化对象。我尝试了几种不同的方法(所有基于流的方法)都有一致的问题。反序列化对象使W3WP的内存从115,000K(正常)到超过2.2GB!而这只是反序列化一个Report对象。加上反序列化非常慢!
我不知道内存中2.2GB的峰值是否是因为 maxReceivedMessageSize 等属性的WCF设置,或者反序列化过程中是否存在漏洞(我目前正在使用DataContractSerializer) )。不管是什么,我都被困住了。
所以,你有它 - 一个大的对象需要穿过电线然后被反序列化而不需要永恒并消耗所有可用的内存。
有没有人有任何建议?我完全乐于接受任何解决方案;我不在乎它有多么不寻常或有创意。唯一的限制是:
谢谢大家!
答案 0 :(得分:0)
我会把它分成多个电话。第一个调用是创建报告并将其保留的请求,并返回标识报告的对象。后续调用是通过将报表对象传递给另一个方法来请求合理的报表。也许请求一系列文件。
除非消费者真的需要同时将所有5000个文件加载到内存中(这听起来很糟糕),否则你应该可以对这些部分进行分块。