2012-11-14 46 views
4

根据微软的样本,这里是一个将如何去流媒体文件throuhg WCF:WCF流 - 谁关闭文件?

// Service class which implements the service contract 
    public class StreamingService : IStreamingSample 
    { 

     public System.IO.Stream GetStream(string data) 
     { 
      //this file path assumes the image is in 
      // the Service folder and the service is executing 
      // in service/bin 
      string filePath = Path.Combine(
       System.Environment.CurrentDirectory, 
       ".\\image.jpg"); 
      //open the file, this could throw an exception 
      //(e.g. if the file is not found) 
      //having includeExceptionDetailInFaults="True" in config 
      // would cause this exception to be returned to the client 
      try 
      { 
       FileStream imageFile = File.OpenRead(filePath); 
       return imageFile; 
      } 
      catch (IOException ex) 
      { 
       Console.WriteLine(
        String.Format("An exception was thrown while trying to open file {0}", filePath)); 
       Console.WriteLine("Exception is: "); 
       Console.WriteLine(ex.ToString()); 
       throw ex; 
      } 
     } 
... 

现在,我怎么知道谁是负责在传输完成释放的FileStream?

编辑:如果代码放在“使用”块中,则在客户端收到任何内容之前流会关闭。

回答

5

服务应该清理,而不是客户端。 WCF的OperationBehaviorAttribute.AutoDisposeParameters的默认值似乎是真实的,因此它应该为您处置。虽然这似乎没有一个固定的答案。

你可以尝试使用OperationContext.OperationCompleted Event

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

把你回来之前。

入住这blog

+0

看起来很有前途,谢谢! –

0

简短回答:调用代码,通过using块。

很长的答案:示例代码永远不应该被视为良好实践的典范,它只是为了说明一个非常具体的概念。真正的代码永远不会有这样的try块,它不会增加代码的价值。错误应记录在最高层,而不是深入。考虑到这一点,样本变成了一个表达式,即File.OpenRead(filePath),它可以简单地插入需要它的using块中。

UPDATE(以后看到更多的代码):

刚刚从函数返回的流,WCF将决定何时处置它。

+1

我不能使用“使用”块,因为这将关闭流。 –

+0

已更新的答案。 –

0

流需要由负责阅读的一方关闭。例如,如果服务将流返回给客户端,则客户端应用程序责任关闭流,因为服务不知道或者在客户端完成读取流时控制该流。此外,由于WCF不知道接收方何时完成阅读,WCF将不会再次关闭流。 :)

HTH, 阿米特·巴蒂亚