Otávio Décio
Otávio Décio

Reputation: 74290

WCF Streaming - who closes the file?

According to Microsoft's samples, here's how one would go about streaming a file throuhg 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;
            }
        }
...

Now, how do I know who's responsible for releasing the FileStream when the transfer is done?

EDIT: If the code is put inside a "using" block the stream gets shut down before the client receives anything.

Upvotes: 5

Views: 1804

Answers (3)

Science_Fiction
Science_Fiction

Reputation: 3433

The service should clean up and not the client. WCF's default for OperationBehaviorAttribute.AutoDisposeParameters seems to be true, therefore it should do the disposing for you. Although there doesn't seem to be a fixed answer on this.

You could try using the OperationContext.OperationCompleted Event:

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

Put that before your return.

Check this blog

Upvotes: 6

amit
amit

Reputation: 2123

The stream needs to be closed by party who is responsible to read it. For example, if service returns the stream to client, it's client application responsibility close the stream as Service doesn't know or have control when client finishes reading stream. Also, WCF will not take care of closing the stream again because of the fact that it doesn't know when receiving party has finished reading. :)

HTH, Amit Bhatia

Upvotes: 0

Christian Hayter
Christian Hayter

Reputation: 31071

Short answer: the calling code, via a using block.

Long answer: sample code should never be held up as an exemplar of good practice, it's only there to illustrate one very specific concept. Real code would never have a try block like that, it adds no value to the code. Errors should be logged at the topmost level, not down in the depths. Bearing that in mind, the sample becomes a single expression, File.OpenRead(filePath), that would be simply plugged into the using block that requires it.

UPDATE (after seeing more code):

Just return the stream from the function, WCF will decide when to dispose it.

Upvotes: 0

Related Questions