我试图通过WCF服务调用将一些大数据保存到数据库。我无法调用该服务。它抛出一个错误:
无法分配268435456字节的托管内存缓冲区。可用内存量可能很低
public async Task<int> UploadExportPackage(DTO.Upload.UploadPackage package)
{
int result = await serviceProxy.UploadResultsAsync(package);
return result;
}
服务器端配置:
<!--
Place limits on the amount of data that can be received in one go.
This helps to protect the server from attack and abuse.
-->
<binding name="primaryBinding"
maxReceivedMessageSize="6000000"
maxBufferSize="6000000"
maxBufferPoolSize="12000000">
<readerQuotas maxArrayLength="6000000"
maxStringContentLength="6000000" />
<!--
Set the security mode. Apply at:
- Transport layer
- Message layer
-->
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpsBinding>
</bindings>
堆栈追踪:
Exception no: 0
下一个例外: 消息:
无法分配268435456字节的托管内存缓冲区。可用内存量可能很低。
堆栈跟踪:
服务器堆栈跟踪:
在System.Runtime.Fx.AllocateByteArray(Int32大小)
在System.Runtime.InternalBufferManager.PooledBufferManager.TakeBuffer(Int32 bufferSize)
在System.ServiceModel.Channels.BufferManagerOutputStream.Init(Int32 initialSize,Int32 maxSizeQuota,Int32 effectiveMaxSize,BufferManager bufferManager)
在System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(消息消息,BufferManager bufferManager,Int32 initialOffset,Int32 maxSizeQuota)
at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(消息消息,Int32 maxMessageSize,BufferManager bufferManager,Int32 messageOffset)
在System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(消息消息,布尔值shouldRecycleBuffer)
在System.ServiceModel.Channels.HttpOutput.SendAsyncResult.SendWithoutChannelBindingToken()
在System.ServiceModel.Channels.HttpOutput.SendAsyncResult.Send()
在System.ServiceModel.Channels.HttpOutput.SendAsyncResult..ctor(HttpOutput httpOutput,HttpResponseMessage httpResponseMessage,Boolean suppressEntityBody,TimeSpan timeout,AsyncCallback callback,Object state)
在System.ServiceModel.Channels.HttpOutput.BeginSendCore(HttpResponseMessage httpResponseMessage,TimeSpan超时,AsyncCallback回调,对象状态)
在System.ServiceModel.Channels.HttpChannelFactory 1.HttpRequestChannel.HttpChannelAsyncRequest.SendWebRequest()
at System.ServiceModel.Channels.HttpChannelFactory
1.HttpRequestChannel.HttpChannelAsyncRequest.BeginSendRequest(消息消息,TimeSpan超时)
在System.ServiceModel.Channels.RequestChannel.BeginRequest(消息消息,TimeSpan超时,AsyncCallback回调,对象状态)
在System.ServiceModel.Channels.SecurityChannelFactory 1.RequestChannelSendAsyncResult.BeginSendCore(IRequestChannel channel, Message message, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Security.ApplySecurityAndSendAsyncResult
1.OnSecureOutgoingMessageComplete(消息消息)
在System.ServiceModel.Security.ApplySecurityAndSendAsyncResult 1.Begin(Message message, SecurityProtocolCorrelationState correlationState)
at System.ServiceModel.Channels.SecurityChannelFactory
1.SecurityRequestChannel.BeginRequest(消息消息,TimeSpan超时,AsyncCallback回调,对象状态)
在System.ServiceModel.Dispatcher.RequestChannelBinder.BeginRequest(消息消息,TimeSpan超时,AsyncCallback回调,对象状态)
在System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartSend(Boolean completedSynchronously)
在System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishEnsureOpen(IAsyncResult result,Boolean completedSynchronously)
在System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartEnsureOpen(Boolean completedSynchronously)
在System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishEnsureInteractiveInit(IAsyncResult result,Boolean completedSynchronously)
在System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartEnsureInteractiveInit()
在System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.Begin()
at System.ServiceModel.Channels.ServiceChannel.BeginCall(String action,Boolean oneway,ProxyOperationRuntime operation,Object [] ins,TimeSpan timeout,AsyncCallback callback,Object asyncState)
在System.ServiceModel.Channels.ServiceChannel.BeginCall(ServiceChannel通道,ProxyOperationRuntime操作,Object [] ins,AsyncCallback回调,Object asyncState)
at System.Threading.Tasks.TaskFactory 1.FromAsyncImpl[TArg1,TArg2,TArg3](Func
6 beginMethod,Func 2 endFunction, Action
1 endAction,TArg1 arg1,TArg2 arg2,TArg3 arg3,Object state,TaskCreationOptions creationOptions)
在System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateGenericTask [T](ServiceChannel频道,ProxyOperationRuntime操作,Object [] inputParameters)
在System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateGenericTask(ServiceChannel频道,ProxyOperationRuntime操作,Object [] inputParameters)
在System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateTask(ServiceChannel频道,IMethodCallMessage methodCall,ProxyOperationRuntime操作)
在System.ServiceModel.Channels.ServiceChannelProxy.InvokeTaskService(IMethodCallMessage methodCall,ProxyOperationRuntime操作)
在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
在[0]处重新抛出异常: 在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg) 在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData,Int32 type) 在RossendaleClient8.DAL.RR.IRossendaleService.UploadResultsAsync(UploadPackage包) 在RossendaleClient8.DAL.RR.RossendaleServiceClient.UploadResultsAsync(UploadPackage包) 在RossendaleClient8.DAL.RossendaleServiceClient.d__13.MoveNext()
下一个例外: 消息:
类型的异常&#39; System.OutOfMemoryException&#39;被扔了。
堆栈跟踪:在System.Runtime.Fx.AllocateByteArray(Int32 size)
答案 0 :(得分:6)
如果您的绑定允许,请尝试使用。您还可以查看TransferMode.Streamed。 来自MSDN:
- 缓冲传输将整个消息保存在内存缓冲区中,直到传输完成。
- 流式传输仅缓冲邮件头并将邮件正文作为流公开,较小的部分可以从中流 一次阅读。
默认的TransferMode是Buffered,因此整个消息被加载到内存中。如果打开Streamed TransferMode,则可以通过编辑MaxBufferSize的值来管理内存使用的大小。
BinaryMessageEncoding反过来允许您压缩数据,通过网络发送。 以下是App.Config内容的示例
<customBinding>
<binding name="primaryBinding" openTimeout="00:01:00" closeTimeout="00:01:00"
sendTimeout="00:30:00" receiveTimeout="00:30:00">
<binaryMessageEncoding compressionFormat="GZip">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binaryMessageEncoding>
<httpsTransport transferMode="Streamed" maxReceivedMessageSize="6000000"
maxBufferSize="6000000" maxBufferPoolSize="12000000" />
</binding>
</customBinding>
代码中的相同配置
private Binding GetBinding()
{
var config = new BindingElementCollection();
config.Add(new BinaryMessageEncodingBindingElement()
{
CompressionFormat = CompressionFormat.GZip,
});
config.Add(new HttpsTransportBindingElement()
{
MaxBufferPoolSize = 12000000,
MaxBufferSize = 6000000,
MaxReceivedMessageSize = 6000000,
TransferMode = TransferMode.Streamed,
});
var resultBinding = new CustomBinding(config)
{
OpenTimeout = TimeSpan.FromMinutes(1),
CloseTimeout = TimeSpan.FromMinutes(1),
ReceiveTimeout = TimeSpan.FromMinutes(1),
SendTimeout = TimeSpan.FromMinutes(1),
};
return resultBinding;
}
答案 1 :(得分:1)
我从未尝试使用WCF发送超过50MB的内容,但我非常确定256MB +文件很容易导致上述问题,我建议您尝试以下方法:
答案 2 :(得分:1)
如前所述,我已将TransferMode更改为“Streamed”,但我也增加了最大缓冲区大小。将超时和maxAllowedContent增加到300mb,以允许上载更大的文件。现在效果很好。
答案 3 :(得分:1)
我知道它可能不适合所有人,但是......
我们最近遇到了类似的问题。在本地调试一些代码时,只有一个开发人员遇到了问题。原来他没有使用 64位版本的 IIS Express 。
答案 4 :(得分:0)
另见OutOfMemoryException while populating MemoryStream: 256MB allocation on 16GB system: 请求的内存逐步加倍,有些内存不能分配额外的内存 - 当你得到异常时就是这样。