EWS GetItem请求+ IncludeMimeContent +巨大邮件= OutOfMemoryException

时间:2011-05-19 12:45:11

标签: c# out-of-memory exchangewebservices large-data

我在Exchange 2007邮箱中有一个200 MB大的电子邮件。别问我怎么那么大;我不知道。但它在邮箱中,它需要以MIME格式出来。为了使其更具挑战性,它需要使用C#中的EWS以MIME格式退出。

从理论上讲,这是小菜一碟,对吧?我所要做的就是:

GetItemType getItemRequest = new GetItemType {
    ItemIds = new ItemIdType[] { sItemId },
    ItemShape = new ItemResponseShapeType {
        BaseShape = DefaultShapeNamesType.IdOnly,
        IncludeMimeContent = true,
        IncludeMimeContentSpecified = true,
        BodyType = BodyTypeResponseType.Best,
        BodyTypeSpecified = true
    }
};

...然后将其发送出去:

GetItemResponseType getItemResponse = oService.GetItem(getItemRequest);

但是有了200 MB的邮件,现实生活很快就会让你头疼。我的程序在占用2GB内存后会出现System.OutOfMemoryException。堆栈跟踪指向我:

System.Text.StringBuilder.ToString()
System.Xml.XmlTextReaderImpl.ParseText()
System.Xml.XmlTextReaderImpl.ParseElementContent()
System.Xml.XmlTextReaderImpl.Read()
System.Xml.XmlTextReader.Read()
System.Xml.XmlReader.ReadStartElement()
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExchangeServiceBinding.Read75_MimeContentType(Boolean isNullable, Boolean checkType)
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExchangeServiceBinding.Read139_MessageType(Boolean isNullable, Boolean checkType)
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExchangeServiceBinding.Read302_ArrayOfRealItemsType(Boolean isNullable, Boolean checkType)
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExchangeServiceBinding.Read310_ItemInfoResponseMessageType(Boolean isNullable, Boolean checkType)
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExchangeServiceBinding.Read315_ArrayOfResponseMessagesType(Boolean isNullable, Boolean checkType)
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExchangeServiceBinding.Read331_GetItemResponseType(Boolean isNullable, Boolean checkType)
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExchangeServiceBinding.Read429_GetItemResponse()
Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer125.Deserialize(XmlSerializationReader reader)
System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
MyAwesomeApp.ExchangeService.ExchangeServiceBinding.GetItem(GetItemType GetItem1)

果然,我的200 MB邮件,作为BASE64编码的XML,正被读入RAM。而且我想在整个调用堆栈中通过各种自动生成的方法将污垢擦到伤口上,它可能会多次存储在RAM中。

令人讨厌的是,在我从方法中获取BASE64编码的MIME消息(适用于较小的消息)之后,我要做的第一件事就是将其写入磁盘并释放保存它的对象以释放内存。我已经有了使用FromBase64Transform解码BASE64的代码,因为它是从磁盘读取的。我想防止像这样的恐怖场景。

话虽这么说,我该怎么做才能避免在RAM中处理XML响应?理想情况下,我想通过磁盘写它然后顺序读取它。任何想法我怎么能这样做而不必完全为EWS推出我自己的SOAP客户端?

Edit2:之前的编辑也无效。重新生成Web服务类打破了它。哦,回到原点。

0 个答案:

没有答案