Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 处置Microsoft.Owin.Hosting.WebApp抛出';System.ObjectDisposedException';_.net_Wpf_Signalr_Owin - Fatal编程技术网

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

.net 处置Microsoft.Owin.Hosting.WebApp抛出';System.ObjectDisposedException';,.net,wpf,signalr,owin,.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 (isD

我们的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;
    }
public void Start()
{
myWebApp=WebApp.Start(url);
}
私有无效处置(bool isDisposing)
{
如果(处置)返回;
if(isDisposing)
myWebApp.Dispose();
这是真的;
}
调用myWebApp.Dispose()会引发“System.ObjectDisposedException”。 我做错什么了吗?Microsoft.Owin.*DLL的版本为2.1.0和SignalR self host 2.0.3


更新:这是我在visual studio中第一次看到异常,因为“在clr异常上中断”设置处于活动状态。这个异常似乎是在内部处理的,不会出现在我们的代码中

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

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

调用
WebApp.Start()
时,它返回一个
IDisposable
的实例,该实例只有
Dispose()
方法,该方法处理
OwinHttpListener

因此,当您处理它时,可以调用它的
dispose()
方法
OwinHttpListener
,该方法处理私有的
HttpListener

但与此同时,
ProcessRequestsAsync()
调用
\u listener.GetContextAsync()
,但
\u listener
已被释放并抛出
ObjectDisposedException
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();
}

因此,如果不重写Katana,就无法解决问题。是吗?@SerG是的,是的。您所能做的就是将WebApp.Start()返回的对象保留为未显示。我不确定双重检查锁定在哪里会有帮助。但是,Dispose方法似乎需要做更多的工作来关闭异步进程,该进程仍在尝试做一些事情,而侦听器正在它下面被处理。在您的情况下,这可能是第一次机会,但如果使用NLog中间件:
appBuilder.UseNLog()
它会将异常记录为错误。