BizTalk自定义管道组件System.OutOfMemoryException

BizTalk自定义管道组件System.OutOfMemoryException,biztalk,custom-component,biztalk-2010,Biztalk,Custom Component,Biztalk 2010,我目前正在开发一个BizTalk自定义发送管道,它接受xml文件并将其转换为Excel。不幸的是,在部署管道之后,我收到了一个System.OutOfMemoryException。我已经包含了IComponent接口的执行方法的代码。欢迎所有建议 public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(ipipipelinecontext pContext,Microsoft.BizTalk.Message.Interop.I

我目前正在开发一个BizTalk自定义发送管道,它接受xml文件并将其转换为Excel。不幸的是,在部署管道之后,我收到了一个
System.OutOfMemoryException
。我已经包含了
IComponent
接口的执行方法的代码。欢迎所有建议

public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(ipipipelinecontext pContext,Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
{
MemoryStream outMemStream=新的MemoryStream();
尝试
{
if(inmsg.BodyPart.Data!=null)
{
//读取来自消息引擎的源消息并将其转换为内存流
字节[]缓冲区=新字节[16*1024];
使用(MemoryStream ms=new MemoryStream())
{
int-read;
而((read=inmsg.BodyPart.Data.read(buffer,0,buffer.Length))>0)
{
ms.Write(缓冲区,0,读取);
}
缓冲区=ms.ToArray();
}
if(缓冲区!=null)
{
var binaryWriter=新的binaryWriter(outMemStream);
写入(缓冲区);
}
OpenXMLOffice oOffice=新的OpenXMLOffice();
outMemStream.Position=0;
oOffice.XMLToExcel(outMemStream,临时文件位置);
inmsg.BodyPart.Data.Position=0;
inmsg.BodyPart.Data=outMemStream;
pContext.ResourceTracker.AddResource(outMemStream);
}
返回消息;
}
捕获(例外情况除外)
{
抛出新的ApplicationException(String.Format(“将XML转换为Excel时出错:{0}-堆栈跟踪:{1}”,例如Message,例如StackTrace));
}
}
以下是最近收到的错误:

Log Name: Application Source: BizTalk Server Date: 2/14/2012 9:29:00 AM Event ID: 5754 Task Category: BizTalk Server Level: Error Keywords: Classic User: N/A Computer: IASDev-PC Description: A message sent to adapter "FILE" on send port "ExcelSendPort" with URI "C:\SeleneFTPFile\Excel\%MessageID%.xml" is suspended. Error details: There was a failure executing the send pipeline: "IAS.SeleneFTPFile.ExcelEncodePipeline, IAS.SeleneFTPFile, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2add433e7764165f" Source: "Excel File Encoder" Send Port: "ExcelSendPort" URI: "C:\SeleneFTPFile\Excel\%MessageID%.xml" Reason: Error converting XML to Excel:Exception of type 'System.OutOfMemoryException' was thrown. - Stack Trace: at System.IO.MemoryStream.set_Capacity(Int32 value) at System.IO.MemoryStream.EnsureCapacity(Int32 value) at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) at IAS.SeleneFTPFile.Components.ExcelPipeline.EncodeExcel.Execute(IPipelineContext pContext, IBaseMessage inmsg) MessageId: {ED37CDD1-EF0C-46E7-9519-061AF3D4F8A4} InstanceID: {B0E448B3-3DAD-4E52-8F87-07C5D5AA5224} 日志名称:应用程序 来源:BizTalk Server 日期:2012年2月14日上午9:29:00 活动编号:5754 任务类别:BizTalk Server 级别:错误 关键词:经典 用户:不适用 计算机:IASDev PC 说明: 发送到发送端口“ExcelSendPort”上适配器“FILE”的URI为“C:\SeleneFTPFile\Excel\%MessageID%.xml”的消息已挂起。 错误详细信息:执行发送管道时失败:“IAS.SeleneFTPFile.ExcelEncodePipeline,IAS.SeleneFTPFile,Version=1.0.0,Culture=neutral,PublicKeyToken=2add433e7764165f”源:“Excel文件编码器”发送端口:“ExcelSendPort”URI:“C:\SeleneFTPFile\Excel\%MessageID%.xml”原因:将XML转换为Excel时出错:引发了类型为“System.OutOfMemoryException”的异常。-堆栈跟踪:位于System.IO.MemoryStream.set_容量(Int32值) 在System.IO.MemoryStream.EnsureCapacity处(Int32值) 在System.IO.MemoryStream.Write(字节[]缓冲区,Int32偏移量,Int32计数) 在IAS.SeleneFTPFile.Components.ExcelPipeline.EncodeExcel.Execute(IPipelineContext pContext,IBaseMessage inmsg)处 消息ID:{ED37CDD1-EF0C-46E7-9519-061AF3D4F8A4} 实例ID:{B0E448B3-3DAD-4E52-8F87-07C5D5AA5224}
您可以尝试预先分配
MemoryStream
缓冲区()。错误消息指出,在执行缓冲写入时,无法为该行分配足够的内存(
ms.write(buffer,0,read);

使用(MemoryStream ms=新的MemoryStream(buffer.Length))
另一个问题是,您的
缓冲区可能会溢出-在写入时会产生此错误(
ms.Write(buffer,0,read)

byte[]buffer=新字节[2*1024*1024];//尝试增加到2MB缓冲区

即使是我也面临同样的问题。我可以发现原因是,即使在执行下面的语句之后,
inmsg.BodyPart.Data
流的流位置也没有前进,并保持为0:

read = inmsg.BodyPart.Data.Read(buffer, 0, buffer.Length)

可能有一件事-BinaryWriter也是IDisposable-@nonnb,那么我应该将BinaryWriter添加到PipelineContext的ResourceTracker中吗?您已经非常严格地限定了BinaryWriter的范围(很好),但是通过显式处理,您可以在GC开始收集它之前释放BinaryWriter。我怀疑这是OutofMemoryException的主要原因。@SilverNinja,我修改了我的MemoryStream,使用缓冲区预先分配它。不幸的是,我仍然收到相同的错误。不过谢谢你的建议。你需要增加缓冲区的大小。您创建的
字节[]
限制为16K…请尝试将其加倍或再乘以1024,得到15MB。您需要确定传入负载的大小,以预测应该使用的缓冲区大小。