Fix Microsoft.Owin.Hosting.WebApp throws 'System.ObjectDisposedException'

We have our own SignalR server in our WPF application. WebApp starts when the application starts. When the application exits, we remove WebApp.

public void Start() { myWebApp = WebApp.Start<MyApp>(url); } private void Dispose(bool isDisposing) { if (disposed) return; if (isDisposing) myWebApp.Dispose(); disposed = true; } 

A call to myWebApp.Dispose () throws a "System.ObjectDisposedException". Am I doing something wrong? Microsoft.Owin libraries. * There is version 2.1.0 and the SignalR 2.0.3 host itself

UPDATE It turns out that this is the first random exception that I see in visual studio, because the parameter "break on clr exceptions" is active. This exception is apparently handled internally and does not turn into our code

+8
wpf owin signalr
source share
1 answer

After studying the source code of Katana, I found the cause of this problem. This is the Microsoft.Owin.Host.HttpListener.OwinHttpListener.ProcessRequestsAsync() method. It starts a while loop containing a call to _listener.GetContextAsync() private HttpListener instance in the try-catch section.

The class also implements IDisposable and contains the Dispose() method. This method provides a private HttpListener instance.

When you call WebApp.Start() , it returns an instance of IDisposable , which has only the Dispose() method, which has an OwinHttpListener .

So, when you destroy it, you call its Dispose() OwinHttpListener , which provides a private HttpListener .

But at the same time, ProcessRequestsAsync() throws _listener.GetContextAsync() , but _listener already placed and throws an ObjectDisposedException . catch locks the exception record and returns from ProcessRequestsAsync() .

I think double check lock in ProcessRequestsAsync() might 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(); } 
+3
source share

All Articles