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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With