我们的
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.ObjectdisposedException’.
难道我做错了什么? Microsoft.Owin.* dll具有版本2.1.0和SignalR自托管2.0.3
更新:事实证明这是我在visual studio中可以看到的第一个机会异常,因为设置“破坏clr异常”是活动的.这个异常似乎是在内部处理的,并没有冒出我们的代码
在探索了Katana源代码之后,我发现了这个问题的原因.它是Microsoft.Owin.Host.HttpListener.OwinHttpListener.ProcessRequestsAsync()方法.它启动while循环,包含在try-catch部分中的私有HttpListener实例的_listener.GetContextAsync()调用.
类也实现了Idisposable并包含dispose()方法.此方法处理私有HttpListener实例.
当你调用WebApp.Start()时,它返回一个Idisposable实例,它只有dispose()方法,它处理OwinHttpListener.
因此,当你处理它时,你调用它的OwinHttpListener的dispose()方法,它处理私有的HttpListener.
但同时ProcessRequestsAsync()调用_listener.GetContextAsync(),但_listener已经处理并抛出ObjectdisposedException. catch块记录异常并从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(); }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。