I spent some time yesterday evening tracking down an issue with a custom WCF transport channel. This particular channel would support the IInputChannel channel shape, but with a twist: it would return a custom implementation of System.ServiceModel.Channels.Message instead of one of the built-in WCF implementations.
There’s nothing wrong with that and it was working just fine in most cases, until I ran into a few scenarios where the OnClose() method of my custom Message class wasn’t being called at all.
After some digging, I discovered that the specific messages this was happening to were not being processed normally by the ServiceHost infrastructure. In particular, they were not being dispatched because no method in the service contract matched the action in the messages, so instead the UnknownMessageReceived event in the ServiceHost instance was being raised.
Our UnknownMessageReceived implementation wasn’t closing messages explicitly, but that was easily corrected, so no problems, right? Wrong. Turns out, that it appears that in WCF 3.0/5 (haven’t checked 4.0 yet), if you do not have an event handler for UnknownMessageReceived, then the messages won’t get closed either.
This seems like a bad bug to me, because since Message implements IDisposable, there’s obviously the expectation that it will hold resources that should be released as soon as possible, so not calling Dispose()
or Closed()
will leak resources and potentially cause trouble.
Attaching an event handler to UnknownMessageReceived just isn’t an option always, and even if it were, there’s no reason why WCF itself shouldn’t be guaranteeing that messages are closed as soon as they aren’t needed.