none
WCF Service hosted on IIS website with TransferMode = Streamed throws w3wp.exe OutOfMemory exception?

    Question

  • I have build a WCF service to upload and download files.

    Service: Hosted on IIS asp.net website:

    Client:  Calling the above service from console application:

    Note: If I change transfer mode to buffered in the client it works and however if Make the transfer mode on the client to Streamed it doesn't and throws outofmemory error.

     

    [ServiceContract]
    public interface IFileTransferService
    {
     [OperationContract(IsOneWay = true)]
     void Upload(FileTransferRequest request);
    }
    
    [MessageContract()]
    public class FileTransferRequest
    {
     [MessageHeader(MustUnderstand = true)]
     public string FileName;
    
     [MessageBodyMember(Order = 1)]
     public System.IO.Stream Data;
    
    }
    
    [AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Required)]
    public class FileTransferService : IFileTransferService
    {
     public FileTransferService()
     {
      HttpContext httpContext = HttpContext.Current;
    
      if (httpContext != null)
      {
       httpContext.Response.BufferOutput = false;
      }
     }
    
     public void Upload(FileTransferRequest request)
     {
      string fileName = System.Guid.NewGuid().ToString() + request.FileName;
    
      if (ConfigurationManager.AppSettings["UploadPath"] == null)
      {
       throw new ApplicationException("Missing upload path");
      }
      
      string uploadPath = "/OutputFeeds";
      string filePath = Path.Combine(Path.GetFullPath(HttpContext.Current.Server.MapPath(uploadPath)), fileName);
    
      FileStream fs = null;
      try
      {
       fs = File.Create(filePath);
       byte[] buffer = new byte[1024];
       int read = 0;
       while ((read = request.Data.Read(buffer, 0, buffer.Length)) != 0)
       {
        fs.Write(buffer, 0, read);
       }
      }
      finally
      {
       if (fs != null)
       {
        fs.Close();
        fs.Dispose();
       }
    
       if (request.Data != null)
       {
        request.Data.Close();
        request.Data.Dispose();
       }
      }
     }
    
    }
    
    <br/>
    
    <system.serviceModel>
     <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
      </serviceHostingEnvironment>
     <bindings>
      <basicHttpBinding>
      <binding name="HttpBinding_MTOM" messageEncoding="Mtom" transferMode="Streamed" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
       <security mode="None">
       <transport clientCredentialType="None" />
       </security>
      </binding>
      
     </bindings>
     <services>
    
      <service behaviorConfiguration="FileTransferServiceBehavior"
      name="FileTransferService">
      <endpoint address="" binding="basicHttpBinding" bindingConfiguration="HttpBinding_MTOM"
       contract="IFileTransferService">
       <identity>
       <dns value="localhost" />
       </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
      
      
     </services>
     <behaviors>
      <serviceBehaviors>
      
      <behavior name="FileTransferServiceBehavior">
       <serviceMetadata httpGetEnabled="true" />
       <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
      
      </serviceBehaviors>
     </behaviors>
     </system.serviceModel>
    

     

    Client App.Config:

     

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
     <system.serviceModel>
      <bindings>
       <basicHttpBinding>
        <binding name="BasicHttpBinding_IFileTransferService" closeTimeout="00:01:00"
         openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
         allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
         maxBufferSize="65536" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
         messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed"
         useDefaultWebProxy="true">
         <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" />
         <security mode="None">
          <transport clientCredentialType="None" proxyCredentialType="None"
           realm="">
           <extendedProtectionPolicy policyEnforcement="Never" />
          </transport>
          <message clientCredentialType="UserName" algorithmSuite="Default" />
         </security>
        </binding>
        
       </basicHttpBinding>
      </bindings>
      <client>
       <endpoint address="http://ht/FileTransferService.svc" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IFileTransferService"
        contract="HobbyTown.IFileTransferService" name="BasicHttpBinding_IFileTransferService" />
       
      </client>
     </system.serviceModel>
    </configuration>
    

    Client Upload Code:

     string inputFile = @"C:\Client\InputFeeds\FullInventory.zip";
          using (FileStream fs = new FileStream(inputFile, FileMode.Open))
          {
            FileTransferServiceClient proxy = new FileTransferServiceClient();
            proxy.Upload("Inventory.Zip", fs);
            //proxy.Upload(trIn);
          }

     



    Thursday, May 05, 2011 8:09 PM

All replies

  • I found an article saying it doesn't support http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/cfe625b2-1890-471b-a4bd-94373daedd39. Is it true?

     


    Thursday, May 05, 2011 8:12 PM
  • I found an article saying it doesn't support http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/cfe625b2-1890-471b-a4bd-94373daedd39. Is it true?

     


    I would wonder if the stream isn't being forced to behave as buffered on the service side. What is FileTransferRequest -- is that third-party? Streaming in WCF generally requires the stream be the only parameter in your exposed service method.
    Microsoft Community Contributor MCTS: .NET 4.0 Service Communication Applications
    Saturday, May 07, 2011 7:45 PM
  • I would wonder if the stream isn't being forced to behave as buffered on the service side. What is FileTransferRequest -- is that third-party? Streaming in WCF generally requires the stream be the only parameter in your exposed service method.

    FileTransferRequest is message contract shown in the example
    RaghuEktron
    Saturday, May 07, 2011 9:37 PM
  • Could you please put the whole stack trace here 

    add the maxBufferPoolSize in both service configuration in binding element

    <binding name="HttpBinding_MTOM" messageEncoding="Mtom" transferMode="Streamed" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"maxBufferPoolSize="2147483647">
     

    also please try changing your client configuration to the following ..

     

     <binding name="BasicHttpBinding_IFileTransferService" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
      maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
    messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed" useDefaultWebProxy="true"> <readerQuotas maxDepth="4000" maxStringContentLength="2147483647" maxArrayLength="2147483647"
    maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
    <security mode="None">

     


    Tanvir Huda Application Architect/Consultant
    Sunday, May 08, 2011 2:57 AM
  • I would wonder if the stream isn't being forced to behave as buffered on the service side. What is FileTransferRequest -- is that third-party? Streaming in WCF generally requires the stream be the only parameter in your exposed service method.

    FileTransferRequest is message contract shown in the example
    RaghuEktron
    http://msdn.microsoft.com/en-us/library/ms733742.aspx
    "Note that adding a second parameter to the following Echo or ProvideInfo operations causes the service model to revert back to a buffered strategy and use the run-time serialization representation of the stream. Only operations with a single input stream parameter are compatible with end-to-end request streaming.
    This rule similarly applies to message contracts. As shown in the following message contract, you can have only a single body member in your message contract that is a stream. If you want to communicate additional information with the stream, this information must be a carried in message headers. The message body is exclusively reserved for the stream content."

    Microsoft Community Contributor MCTS: .NET 4.0 Service Communication Applications
    Sunday, May 08, 2011 9:01 AM
  •  

    add the maxBufferPoolSize in both service configuration in binding element

     



    Tanvir Huda Application Architect/Consultant
    Tanvir, I changed the config file as per you suggestion and it didn't work. Reg. the complete trace,  the visual studio pops on the server where service is hosted with outofmemory exception and it doesn't even let me debug or see more information. "An Unhandled exception (System.OutOfMemoryException") occured in W3wp.exe [7156]"



    RaghuEktron
    Sunday, May 08, 2011 8:56 PM
  • AndrewBadera,
    http://msdn.microsoft.com/en-us/library/ms733742.aspx
    "Note that adding a second parameter to the following Echo or ProvideInfo operations causes the service model to revert back to a buffered strategy and use the run-time serialization representation of the stream. Only operations with a single input stream parameter are compatible with end-to-end request streaming.
    This rule similarly applies to message contracts. As shown in the following message contract, you can have only a single body member in your message contract that is a stream. If you want to communicate additional information with the stream, this information must be a carried in message headers. The message body is exclusively reserved for the stream content."


    Andrew, I changed the service contract as per your suggestion however it didnt' work and same exception.

     

     

    [ServiceContract]
    public interface IFileTransferService
    {
     [OperationContract(IsOneWay = true)]
     void Upload(System.IO.Stream stream);
    }
    
    
     string inputFile = @"C:\Client\InputFeeds\FullInventory.zip";
      using (FileStream fs = new FileStream(inputFile, FileMode.Open))
      {
      FileTransferServiceClient proxy = new FileTransferServiceClient();
      proxy.Upload(fs);
      
      }
    

     

    I found this article http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/0ee098e2-b317-405a-bddc-78d687fffc37/ and not sure if this is similar issue.

     




    Sunday, May 08, 2011 9:11 PM