5

我在一个 200 MB 大的 Exchange 2007 邮箱中有一封电子邮件。不要问我它是怎么变得这么大的;我不知道。但它在邮箱中,需要以 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 服务类破坏了它。哦,好吧,回到第一方。

4

0 回答 0