Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to abort a stream from WCF service without reading it to end?

This is a problems I've been investigating in the last week and can't find any solution. Found posts asking the same but never getting an answer, hopefully this will help others as well.

I have a WCF service that returns an object containing a stream inside it. I use basicHttpBinding with streamed transfer and Mtom to send it to the client.

Client calls the WCF service and closes the proxy immediately after it receives the response object.

Next, the client reads the stream it got from the WCF service and writes it to a file on the local disk. All of this works fine.

My problem is when the client wants to abort the operation and stop downloading the data from the WCF service. If I call .close() on the stream, e.g: serverReply.DataStream.Close(); then it blocks and reads the whole stream from the WCF service till its end before continuing. The stream can be quite large and the network is not always fast.

This is very undesirable for both network resource usage, which is basically wasted on data that has no use anymore. And since basicHttpBinding allows only two concurrent TCP connections (by default) to the WCF service server, it blocks other connection attempts until the stream is read till its end.

I could increase the number of concurrent connections, but that would be a bad solution as it would create an opening for trouble.

For example, 20 aborted downloads that are still downloading the data to throw it away. I need to make the transfer stop completely.

On the client, the stream object is just a regular Stream class, so it only has the close method, nothing else.

Calling .close() or .abort() on the proxy object doesn't help, neither does destroying it using .dispose() or any other method. On the server side, I handle the OperationContext.OperationCompleted event, but it is not fired until the data from the stream is read till the end.

So the question is, how do I close/abort the stream without reading it entirely?

like image 681
Yev Avatar asked Jul 29 '12 14:07

Yev


1 Answers

After investigation I found that the WCF client will keep reading from the stream until closeTimeout ellapsed, then it will abort connection. You might decrease closeTimeout on client to minimize the problem.

NOTE: You should wrap the code that disposes a stream into try/catch block. The stream.Dispose() method will throw TimeoutException which brakes a guideline of not throwing exceptions in Dispose method.

like image 182
Peter Avatar answered Nov 04 '22 21:11

Peter