|
In a lot of WCF
streaming applications it's common to see a message contract like this.
[MessageContract]
public class
DownloadFileRequest
{
[MessageHeader]
private string filename;
[MessageHeader]
private int length;
[MessageBodyMember]
private Stream fileStream;
public DownloadFileRequest()
{
}
}
This often brings
up the question "How can I release the stream when the streaming is
completed?". I just noticed a nice attempt by using a simple polling
mechanism in this article http://www.codeproject.com/WCF/WCF_FileTransfer_Progress.asp. But, there is much simpler and elegant way to do this. You simply have
to implement IDisposable interface in your message contract and clean up the
stream in the Dispose method.
[MessageContract] public class DownloadFileRequest : IDisposable { [MessageHeader] private string filename; [MessageHeader] private int length; [MessageBodyMember] private Stream fileStream; public DownloadFileRequest() { } public void Dispose() { if(fileStream != null) { fileStream.Dispose(); fileStream = null; } } }
Once the message has been fully streamed the dispatcher runtime will call Dispose in all input/output parameter objects used to construct the message.
In to a little bit of
internals like always ;). I looked up where exactly this happens in the
reflector.
As far as I can
understand this work is done in MessageRpc.DisposeParameterList method.
private void
DisposeParameterList(object[]
parameters)
{
IDisposable
disposable = null;
if
(parameters != null)
{
foreach
(object
obj2 in
parameters)
{
disposable
= obj2 as
IDisposable;
if
(disposable != null)
{
try
{
disposable.Dispose();
}
catch
(Exception
exception)
{
if (DiagnosticUtility.IsFatal(exception))
{
throw;
}
this.channelHandler.HandleError(exception);
}
}
}
}
}
So obviously if our
Message contract implements IDisposable it will be perfectly disposed by this
function.
Have fun!
|