是否有必要关闭WebInvoke方法的流

时间:2012-12-19 12:02:55

标签: c# wcf streaming dispose wcf-web-api

我有一个服务接口,其方法的参数类型为Stream。我应该在读完此流中的所有数据后关闭流,还是在方法调用完成后由WCF运行时完成?

我见过的大多数示例,只读取流中的数据,但不要在流上调用Close或Dispose。

通常我会说我不必关闭流导致类不是流的所有者,但原因是为什么问这个问题是我们目前正在调查我们系统中的一个问题,即一些Android使用HTTP-Post将数据发送到此服务的客户端有时会打开未连接的打开连接(使用netstat进行分析,列出ESTABLISHED Tcp连接)。

[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;
  }

服务/装订的配置

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

1 个答案:

答案 0 :(得分:2)

控制关闭或不关闭参数的行为的属性是OperationBehaviorAttribute.AutoDisposeParameters属性,可用于偏离默认行为true,关于Stream参数关闭退出方法。这就是您经常看不到参数显式关闭的原因。如果您要覆盖默认行为,可以通过close the Stream once the operation has completed事件明确控制和OperationCompleted

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;
}

请注意,您收到了Stream自己的副本,而不是对客户Stream的引用,因此您有责任关闭它。