Question

I have a service interface with a method that has a parameter of type Stream. Should i close the stream after i have read all data from this stream or is this done by the WCF Runtime when the method call is completed?

The most examples i have seen, do only read the data from the stream, but do not call Close or Dispose on the Stream.

Normally i would say i do not have to close the stream cause the class is not the owner of the stream, but the reason is why is ask this question is that we are currently investigating a problem in our system, that some Android Clients, that use HTTP-Post to send data to this service sometimes have open connections that aren´t closed (Analyzed with netstat which list ESTABLISHED Tcp connections).

[ServiceContract]
public interface IStreamedService {
    [OperationContract]
    [WebInvoke]
    Stream PullMessage(Stream incomingStream);
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, UseSynchronizationContext = false)]
public class MyService : IStreamedService  {

  public System.IO.Stream PullMessage(System.IO.Stream incomingStream) {
       // using(incomingStream) {
       // Read data from stream
       // }

       Stream outgoingStream = // assigned by omitted code;
       return outgoingStream;
  }

Configuration of the Service/Binding

<webHttpBinding>
  <binding name="WebHttpBindingConfiguration" 
           transferMode="Streamed"
           maxReceivedMessageSize="1048576"
           receiveTimeout="00:10:00" 
           sendTimeout="00:10:00"
           closeTimeout="00:10:00"/>
</webHttpBinding>
Was it helpful?

Solution

The property which controls the behavior of closing or not closing the parameter is the OperationBehaviorAttribute.AutoDisposeParameters property and can be used to deviate from the default behavior of true with regards to the Stream parameter being closed once it exits the method. This is the reason you do not often times see the explicit closing of the parameter. If you want to override default behavior, you can take explicit control and close the Stream once the operation has completed via the OperationCompleted event.

public Stream GetFile(string path) {
   Sream fileStream = null;    

   try   
   {
      fileStream = File.OpenRead(path);
   }
   catch(Exception)
   {
      return null;
   }

   OperationContext clientContext = OperationContext.Current;
clientContext.OperationCompleted += new EventHandler(delegate(object sender, EventArgs args)
   {
      if (fileStream != null)
         fileStream.Dispose();
   });

       return fileStream;
}

Keep in mind that you are receiving your own copy of the Stream, not a reference to the clients Stream and thus you are responsible for closing it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top