我在BizTalk中创建一个自定义接收管道,它将接收包含word文档作为base64字符串的消息。这会将字符串从管道配置中设置的节点提取到memoryStream中,并将其传递给Apose.Words,将其转换为PDF并将其保存到文件中。
从邮件中删除base64字符串,然后将更新的邮件分配回邮件正文。然后在消息中提升新创建的文件的路径。
我的问题是运行此管道的主机内存不断增加,并且似乎没有释放任何资源。目前它的运行速度为250MB并且没有下降。这会导致问题,因为后续电话不能及时处理。
管道组件:
public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
{
string fileName = GenerateFileName();
XmlTextReader reader = new XmlTextReader(pInMsg.BodyPart.GetOriginalDataStream());
var removeNodeReader = new StoreAndRemoveReader(reader, nodeNameOfEncodedFileContents, fileName);
XmlTranslatorStream translatorStream = new XmlTranslatorStream(removeNodeReader);
pInMsg.Context.Write(contextKeyForDocumentFilePath, contextNSForDocumentFilePath, fileName);
pInMsg.BodyPart.Data = translatorStream;
return pInMsg;
}
StoreAndRemoveReader: (这取自http://biztalkmessages.vansplunteren.net/articles/dealing-with-base64/)
public class StoreAndRemoveReader : XmlReader
{
private bool inAttribute;
private XmlReader wrappedReader;
private string nodeNameOfEncodedFileContents;
private string documentFilePath;
public StoreAndRemoveReader(XmlReader wrappedReader,
string nodeNameOfEncodedFileContents,
string documentFilePath)
{
this.wrappedReader = wrappedReader;
this.nodeNameOfEncodedFileContents = nodeNameOfEncodedFileContents;
this.documentFilePath = documentFilePath;
}
public override bool Read()
{
Boolean result = wrappedReader.Read();
if (wrappedReader.IsStartElement() && wrappedReader.LocalName == nodeNameOfEncodedFileContents)
{
if (wrappedReader.IsEmptyElement)
{
wrappedReader.Read();
}
else
{
Base64DecodeDocument(wrappedReader);
}
}
return result;
}
private void Base64DecodeDocument(XmlReader reader)
{
byte[] buffer = new byte[1000];
int readBytes = 0;
//FileStream outputFile = new FileStream(this.documentFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.Write);
using (var outputStream = new MemoryStream(307200))
{
BinaryWriter bw = new BinaryWriter(outputStream);
while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, 1000)) > 0)
{
bw.Write(buffer, 0, readBytes);
}
//File.WriteAllText(this.documentFilePath, "test");
WordToPDFConversion.ConvertWordDocumentToPdf(outputStream, this.documentFilePath);
}
}
我已尝试在XmlTextReader和StoreAndRemoveReader上的管道组件中使用语句,但这并不起作用,因为我认为它会关闭传入消息的流。
我已经尝试过运行Aspose独立版,它确实使用了大量内存,但它确实会在之后清除它。
我可以在管道组件中处理读者,还是有更好的方法来提取数据?
答案 0 :(得分:1)
250MB并不是特别大。你检查过Throttling了吗?
另外,是否有理由初始化300MB MemoryStream? MemoryStream可以自动扩展。
建议:
如果你真的想变得聪明,可以在Stream接口中再次包装ReadElementContentAsBase64操作。但我认为你不需要那么远。
答案 1 :(得分:0)
我太过全神贯注于内存使用情况,我在尝试进行pdf转换时忽略了主机的CPU使用率。我已经添加了一个额外的BizTalk服务器来共享负载,CPU使用率从单个服务器上的95%〜变为每个服务器上的10%左右。