views:

27

answers:

2

I have problem with WCF service. When I am downloading 2 files everything works fine ( less than 1 minute), but when I'm trying downloading more than 3 files there is going something bad . I'm waiting and waiting and nothing :/ Every file has about 1 MB.

Dictionary<FileIdentifier, Stream> data = new Dictionary<FileIdentifier, Stream>();

 foreach (string path in paths)
 {

    using (var client = new ServiceClient())
    {
        var stream = client.GetFile(path);

        data[fileIdentifier] = stream;
     }

 }

Method at WCF Service:

public Stream GetFile(string path)
        {
             FileStream fs = new FileStream(stream, FileMode.Open);
            fs.Close();
            return fs;

        }

config of WCF service:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <system.serviceModel>
    <client />
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpBindingConfiguration" closeTimeout="00:10:00"
          openTimeout="00:15:00" receiveTimeout="00:15:00" sendTimeout="00:15:00"
          allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
          maxBufferSize="2097152000" maxBufferPoolSize="524288000" maxReceivedMessageSize="2097152000"
          messageEncoding="Text" textEncoding="utf-8" transferMode="Streamed"
          useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="524288000"
            maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="FileServer.Service" behaviorConfiguration="FileServer.Service1Behavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8731/Design_Time_Addresses/Server.FileServer/Service/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address="" contract="FileServer.IService" binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfiguration">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="FileServer.Service1Behavior">
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True" />
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.web>
    <compilation debug="true" />
    <httpRuntime maxRequestLength="2097151" executionTimeout="1000" />
    <customErrors mode="RemoteOnly" />
  </system.web>
  <system.webServer>
    <directoryBrowse enabled="false" />
  </system.webServer>
</configuration>
+1  A: 

Instead of returning a stream, read the stream into a byte array and then return the byte array.

Shiraz Bhaiji
This would mean that the data would be buffered and the message size would be potentially huge (at 1MB per file). Streaming is the correct way to go (see @Johann's answer).
Tim Roberts
+3  A: 

You should not close the stream on the service side.

Here is how you would do:

  1. Open stream on service
  2. Return stream to client
  3. Read the stream on the client
  4. Close the stream on the client
  5. WCF will take care of closing the service stream for you
Johann Blais
+1 Not sure why it appears to work for 1 or 2 files, but yes, you shouldn't close the stream on the server side.
Tim Roberts