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

Jeh*_*hof 23 c# streaming wcf dispose wcf-web-api

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

我见过的大多数例子,只读取流中的数据,但不要在Stream上调用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;
  }
Run Code Online (Sandbox Code Playgroud)

服务/绑定的配置

<webHttpBinding>
  <binding name="WebHttpBindingConfiguration" 
           transferMode="Streamed"
           maxReceivedMessageSize="1048576"
           receiveTimeout="00:10:00" 
           sendTimeout="00:10:00"
           closeTimeout="00:10:00"/>
</webHttpBinding>
Run Code Online (Sandbox Code Playgroud)

Aar*_*ver 2

控制关闭或不关闭参数行为的属性是属性OperationBehaviorAttribute.AutoDisposeParameters,可用于偏离关于Stream退出方法后关闭参数的默认行为 true。这就是您经常不会看到参数显式关闭的原因。如果要覆盖默认行为,可以通过OperationCompleted事件进行显式控制并在操作完成后关闭 Stream

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

请记住,您收到的是您自己的副本Stream,而不是对客户的参考Stream,因此您有责任关闭它。