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

Tar*_*ada 5 c# out-of-memory large-data exchangewebservices

我在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
    }
};
Run Code Online (Sandbox Code Playgroud)

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

GetItemResponseType getItemResponse = oService.GetItem(getItemRequest);
Run Code Online (Sandbox Code Playgroud)

但是,通过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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

Edit2:以前的编辑也不起作用.重新生成Web服务类打破了它.哦,回到原点.