Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy is WCF reading input stream to EOF on Close()?
    primarykey
    data
    text
    <p>We're using WCF to build a simple web service which our product uses to upload large files over a WAN link. It's supposed to be a simple HTTP PUT, and it's working fine for the most part.</p> <p>Here's a simplified version of the service contract:</p> <pre><code>[ServiceContract, XmlSerializerFormat] public interface IReplicationWebService { [OperationContract] [WebInvoke(Method = "PUT", UriTemplate = "agents/{sourceName}/epoch/{guid}/{number}/{type}")] ReplayResult PutEpochFile(string sourceName, string guid, string number, string type, Stream stream); } </code></pre> <p>In the implementation of this contract, we read data from <code>stream</code> and write it out to a file. This works great, so we added some error handling for cases when there's not enough disk space to store the file. Here's roughly what it looks like:</p> <pre><code> public ReplayResult PutEpochFile(string sourceName, string guid, string number, string type, Stream inStream) { //Stuff snipped try { //Read from the stream and write to the file } catch (IOException ioe) { //IOException may mean no disk space try { inStream.Close(); } // if instream caused the IOException, close may throw catch { } _logger.Debug(ioe.ToString()); throw new FaultException&lt;IOException&gt;(ioe, new FaultReason(ioe.Message), new FaultCode("IO")); } } </code></pre> <p>To test this, I'm sending a 100GB file to a server that doesn't have enough space for the file. As expected this throws an exception, but the call to <code>inStream.Close()</code> appeared to hang. I checked into it, and what's actually happening is that the call to <code>Close()</code> made its way through the WCF plumbing until it reached <code>System.ServiceModel.Channels.DrainOnCloseStream.Close()</code>, which according to Reflector allocates a <code>Byte[]</code> buffer and keeps reading from the stream until it's at EOF.</p> <p>In other words, the <code>Close</code> call is reading the entire 100GB of test data from the stream before returning!</p> <p>Now it may be that I don't need to call <code>Close()</code> on this stream. If that's the case I'd like an explanation as to why. But more importantly, I'd appreciate it if anyone could explain to me why <code>Close()</code> is behaving this way, why it's not considered a bug, and how to reconfigure WCF so that doesn't happen.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload