53

Let's say I have the following WCF implementation:

public Stream Download(string path)
{
    FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
    return stream;
}

Who's responsible for disposing the returned value? After all, a network failure might occur, hence the consumer might not be able to dispose it.

Ron Klein
  • 9,178
  • 9
  • 55
  • 88
  • @Magnus, as I described above, the consumer might not be able to dispose it, since there might be a network failure. – Ron Klein Jun 26 '11 at 10:30
  • 5
    @Magnus, hmmmmm, guessing is great, but I'd like to have a sure answer :-) – Ron Klein Jun 26 '11 at 10:55
  • 2
    Having the consumer dispose the return stream would have no bearing to the object reference on the server side, since the client is getting a serialized version of the object and will never have an object reference to it's location on the server. – user1060500 Aug 12 '13 at 19:04

3 Answers3

50

Service is responsible for closing stream and unless you change default behavior it does it automatically (the behavior with defalut values is always used). If you set OperationBehavior.AutoDisposeParameters to false you must register handler for OperationContext.OperationCompleted and dispose the stream in the handler as described here.

Client cannot close the stream because client has a different one - you are not passing reference to your stream or reference to your file handler. Internally file content is copied to transport and client processes it in its own stream instance (where he is responsible for disposing it).

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • 1
    Nice explanation but take into account @peter-sladek's answer if you are experiencing undisposed streams in response message contracts, for my own experience I can vouch for it – Ferran Salguero Sep 16 '15 at 14:09
34

If you wrap the Stream in MessageContract (so you could sent more information in headers), beware that the Stream would not be disposed automatically! As the name of attribute OperationBehavior.AutoDisposeParameters suggests, WCF automatically disposes input/output parameters and thus you have to implement IDisposable on your MessageContract class and close the stream there.

Peter Sladek
  • 900
  • 9
  • 8
  • 1
    So are you saying if I have a Stream as a property in my Response class, that the response class would need to implement IDisposable and dispose of the stream there? In other words, WCF will ensure the Response is disposed, and my responsibility is to make sure that the Response class proxies that Dispose to the stream property? – AaronLS Apr 30 '14 at 20:03
  • If using message contracts, yes. At least according to my tests back in 2011. You should definitely do some testing to verify if it is still needed. – Peter Sladek May 09 '14 at 20:56
  • Then avoid message contracts which generally for some fine grained control. Most business applications won't need message contracts. – ZZZ Jul 25 '14 at 13:13
2

You can dispose returned stream in WCF like below

FileStream stream=null;
OperationContext clientContext = OperationContext.Current;
clientContext.OperationCompleted += (sender, args) =>
{
    if (stream != null)
        stream.Dispose();
};

stream = new FileStream(path, FileMode.Open, FileAccess.Read);
return stream;
jessehouwing
  • 106,458
  • 22
  • 256
  • 341
Jameel Moideen
  • 7,542
  • 12
  • 51
  • 79