无法分配268435456字节的托管内存缓冲区.可用内存量可能很低

use*_*674 4 .net c# wcf

我试图通过WCF服务调用将一些大数据保存到数据库.我无法调用该服务.它抛出一个错误:

无法分配268435456字节的托管内存缓冲区.可用内存量可能很低

public async Task<int> UploadExportPackage(DTO.Upload.UploadPackage package)
{
    int result = await serviceProxy.UploadResultsAsync(package);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

服务器端配置:

    <!-- 
      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>
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

Exception no: 0 
Run Code Online (Sandbox Code Playgroud)

下一个例外:消息:

无法分配268435456字节的托管内存缓冲区.可用内存量可能很低.

堆栈跟踪:服务器堆栈跟踪:在System.Runtime.Fx.AllocateByteArray(的Int32大小)在System.Runtime.InternalBufferManager.PooledBufferManager.TakeBuffer(的Int32缓冲区大小)在System.ServiceModel.Channels.BufferManagerOutputStream.Init(的Int32 INITIALSIZE,的Int32 maxSizeQuota, INT32 effectiveMaxSize,BufferManager bufferManager)在System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(消息消息,BufferManager bufferManager,INT32 initialOffset,INT32 maxSizeQuota)在System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(消息消息,INT32 maxMessageSize,BufferManager bufferManager ,System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(消息消息,布尔值为shouldRecycleBuffer)处于System.ServiceModel.Cn上的System.ServiceModel.Channels.HttpOutput.SendAsyncResult.SendWithoutChannelBindingToken()处于System.ServiceModel.Channels.HttpOutput.SendAsyncResult.Send()处System.ServiceModel.Channels.HttpOutput.SendAsyncResult..ctor(高程 tpOutput httpOutput,HttpResponseMessage httpResponseMessage,布尔suppressEntityBody在System.ServiceModel.Channels.HttpChannelFactory,时间跨度超时回调的AsyncCallback,对象状态)在System.ServiceModel.Channels.HttpOutput.BeginSendCore(HttpResponseMessage httpResponseMessage,时间跨度超时回调的AsyncCallback,对象状态)1.HttpRequestChannel.HttpChannelAsyncRequest.SendWebRequest() at System.ServiceModel.Channels.HttpChannelFactory1 System.ServiceModel.Channels.SecurityChannelFactory上的System.ServiceModel.Channels.RequestChannel.BeginRequest(消息消息,TimeSpan超时,AsyncCallback回调,对象状态)中的.HttpRequestChannel.HttpChannelAsyncRequest.BeginSendRequest(消息消息,TimeSpan超时)1.RequestChannelSendAsyncResult.BeginSendCore(IRequestChannel channel, Message message, TimeSpan timeout, AsyncCallback callback, Object state) at System.ServiceModel.Security.ApplySecurityAndSendAsyncResult1.OnSecureOutgoingMessageComplete(消息消息) )在System.ServiceModel.Security.ApplySecurityAndSendAsyncResult 1.Begin(Message message, SecurityProtocolCorrelationState correlationState) at System.ServiceModel.Channels.SecurityChannelFactory1.SecurityRequestChannel.BeginRequest(消息消息,时间跨度超时回调的AsyncCallback,对象状态)在System.ServiceModel.Dispatcher.RequestChannelBinder.BeginRequest(消息消息,时间跨度超时回调的AsyncCallback,对象统计 e)System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartSend(Boolean completedSynchronously)在System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartEnsureOpen的System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishEnsureOpen(IAsyncResult result,Boolean completedSynchronously)中的System.ServiceModel.Channels.ServiceChannel.布局completedSynchronously)在System.ServiceModel.CandishEnsureInteractiveInit(IAsyncResult result,Boolean completedSynchronously)System.ServiceModels.Channel.SendAsyncResult.StartEnsureInteractiveInit()at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.Begin()在System.ServiceModel.Channels.ServiceChannel.BeginCall在System.ServiceModel.Channels.ServiceChannel.BeginCall(ServiceChannel通道,ProxyOperationRuntime操作(字符串动作,布尔单向,ProxyOperationRuntime操作,对象[]插件,时间跨度超时回调的AsyncCallback,对象asyncState) ,Object [] ins,AsyncCallback cal lback,在System.Threading.Tasks.TaskFactory对象asyncState)1.FromAsyncImpl[TArg1,TArg2,TArg3](Func6 beginMethod,Func键2 endFunction, Action1个endAction,TArg1 ARG1,TArg2 ARG2,TArg3 ARG3,在System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateGenericTask对象状态,TaskCreationOptions creationOptions)[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(即时聊天消息)

在异常重新抛出[0]:在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(即时聊天reqMsg,即时聊天retMsg)处RossendaleClient8.DAL System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&MSGDATA,的Int32类型).位于RossendaleClient8.DAL.RossendaleServiceClient.d__13.MoveNext()的RossendaleClient8.DAL.RR.RossendaleServiceClient.UploadResultsAsync(UploadPackage包)中的RR.IRossendaleService.UploadResultsAsync(UploadPackage包)

下一个例外:消息:

抛出了类型'System.OutOfMemoryException'的异常.

堆栈跟踪:在System.Runtime.Fx.AllocateByteArray(Int32大小)

Vla*_*mir 6

如果您的绑定允许,请尝试使用TransferMode.Streamed.您还可以查看BinaryMessageEncoding.来自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>
Run Code Online (Sandbox Code Playgroud)

代码中的配置相同

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


use*_*674 3

如前所述,我已将 TransferMode 更改为“Streamed”,但我还增加了最大缓冲区大小。将超时和 maxAllowedContent 增加到 300mb,以允许上传更大的文件。现在效果很好。