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

标签 .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;
    }

对 myWebApp.Dispose() 的调用引发“System.ObjectDisposeException”。 难道我做错了什么? Microsoft.Owin.* dll 的版本为 2.1.0,SignalR 自主机为 2.0.3

更新:事实证明,这是我在 Visual Studio 中看到的第一次机会异常,因为设置“中断 clr 异常”处于事件状态。这个异常似乎是在内部处理的,不会冒泡到我们的代码中

最佳答案

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

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

当您调用 WebApp.Start() 时,它会返回 IDisposable 的实例,该实例仅具有 Dispose() 方法,该方法可处理 OwinHttpListener.

因此,当您处置它时,您可以调用其 OwinHttpListenerDispose() 方法,该方法会处置私有(private) HttpListener

但同时 ProcessRequestsAsync() 调用 _listener.GetContextAsync(),但 _listener 已被释放并抛出 ObjectDispositedException catch block 记录异常并从 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();
}

关于.net - 处置 Microsoft.Owin.Hosting.WebApp 抛出 'System.ObjectDisposedException',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22982278/

相关文章:

c# - 如何更改 HttpRequestMessage 的 header 值

wpf - 在 XAML 中应用控制模板

c# - Azure 移动服务 Web Api 上的 SignalR CORS

c# - 重启后台 worker

.net - 在部署环境之间管理复杂的 Web.Config 文件

c# - .Net 对结构类型的泛型约束

c# - 当 DataContext 更改时,WPF 绑定(bind) OneWayToSource 将源属性设置为 ""

wpf - MVVM 模型中的非阻塞延迟加载属性

signalr - 使用 Signalr/PersistentConnection 将服务器消息发送到连接的客户端

signalr - 如何仅向 SignalR 中的调用方客户端发送消息?