.net 处置Microsoft.Owin.Hosting.WebApp抛出';System.ObjectDisposedException';
我们的WPF应用程序中有一个自托管的SignalR服务器。WebApp在应用程序启动时启动。在应用程序退出时,我们将处理WebApp.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
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()
它会将异常记录为错误。