处置Microsoft.Owin.Hosting.WebApp会抛出'System.ObjectDisposedException'

Hel*_*aon 8 .net wpf signalr owin

我们的WPF应用程序中有一个自托管的SignalR服务器.WebApp在应用程序启动时启动.在应用程序退出时,我们处理WebApp.

    public void Start()
    {
        myWebApp = WebApp.Start<MyApp>(url);
    }

    private void Dispose(bool isDisposing)
    {
        if (disposed) return;

        if (isDisposing)
            myWebApp.Dispose();

        disposed = true;
    }
Run Code Online (Sandbox Code Playgroud)

对myWebApp.Dispose()的调用引发了'System.ObjectDisposedException'.难道我做错了什么?Microsoft.Owin.*dll具有版本2.1.0和SignalR自托管2.0.3

更新:事实证明这是我在visual studio中可以看到的第一个机会异常,因为设置"破坏clr异常"是活动的.这个例外似乎是在内部处理的,并没有冒出我们的代码

小智 3

在探索Katana源代码后,我找到了这个问题的原因。这就是Microsoft.Owin.Host.HttpListener.OwinHttpListener.ProcessRequestsAsync()方法。它启动 while 循环,包含在 try-catch 部分_listener.GetContextAsync()调用私有实例。HttpListener

类还实现IDisposable并包含一个Dispose()方法。此方法处置私有HttpListener实例。

当您调用它时WebApp.Start(),它会返回一个 的实例IDisposable,该实例只有Dispose()方法,即 disposes OwinHttpListener

因此,当您处置它时,您可以调用它的Dispose()方法OwinHttpListener,该方法会处置 private HttpListener

但同时ProcessRequestsAsync()调用_listener.GetContextAsync(),却_listener已经被释放并抛出ObjectDisposedExceptioncatch块记录异常并从ProcessRequestsAsync().

我认为,双重检查锁定ProcessRequestsAsync()可能是一个不错的选择。

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();
}
Run Code Online (Sandbox Code Playgroud)