Disposing Microsoft.Owin.Hosting.WebApp throws 'System.ObjectDisposedException'
After exploring the Katana source code, I found a reason for this problem. It is the Microsoft.Owin.Host.HttpListener.OwinHttpListener.ProcessRequestsAsync()
method. It starts while-loop containing _listener.GetContextAsync()
call of a private HttpListener
instance in try-catch section.
Also class implements IDisposable
and contains a Dispose()
method. This method disposes the private HttpListener
instance.
When you call WebApp.Start()
it returns an instance of IDisposable
, that only has Dispose()
method, that disposes OwinHttpListener
.
So, when you dispose it, you call its Dispose()
method of OwinHttpListener
, which disposes the private HttpListener
.
But at the same time ProcessRequestsAsync()
calls _listener.GetContextAsync()
, but _listener
is already disposed and throws ObjectDisposedException
. catch
block log the exception and returns from ProcessRequestsAsync()
.
I think, that double check lock in ProcessRequestsAsync()
may be a good option.
private async void ProcessRequestsAsync(){ while (_listener.IsListening && CanAcceptMoreRequests) { Interlocked.Increment(ref _currentOutstandingAccepts); HttpListenerContext context; try { context = await _listener.GetContextAsync(); } (SOME_OTHER_CATCHES) catch (ObjectDisposedException ode) { // These happen if HttpListener has been disposed Interlocked.Decrement(ref _currentOutstandingAccepts); LogHelper.LogException(_logger, "Accept", ode); return; } (SOME_OTHER_CODE) }}public void Dispose(){ if (_listener.IsListening) { _listener.Stop(); } ((IDisposable)_listener).Dispose();}