我正在创建一个监听特定 Http 请求的 Windows 服务。我正在一个单独的任务中运行 httpListener
。当服务停止时,我关闭监听器实例。但似乎 http ListenerContext 正在等待传入请求,并且当监听器关闭时,我收到以下错误
Cannot access a disposed object. Object name: 'System.Net.HttpListener'.
即使我使用某种机制通知 StartListening()
监听已停止,它也不会运行,因为相应线程的执行停留在 HttpListenerContext context = wait _listener.GetContextAsync( );
直到请求到达。
public void StartListening() {
_listener.Start();
_logger.LogDebug("Http Listening started");
Task.Run(async () => {
while (true) {
try {
if (isOpen == false) {
return 0;
}
HttpListenerContext context = await _listener.GetContextAsync();
HttpListenerRequest request = context.Request;
//processing of the requests url/////
var newUri = request.Url.AbsoluteUri;
_concurrentUrlQueue.Enqueue(newUri);
if (ConcurentUrlQueueChanged != null) ConcurentUrlQueueChanged(this, new EventArgs());
}
catch (Exception e) {
_logger.LogError("Error at get listening context, Message: " + e.Message);
}
}
});
}
public void StopListening() {
isOpen = false;
_logger.LogDebug("Http Listening Stop");
_listener.Close();
}
这是关闭正在监听获取上下文的 http 监听器的适当方法。我使用的代码如下。 谢谢..
最佳答案
我找到了解决方案。据我了解,listener.GetContextAsync() 是一种阻塞方法,只有在检测到新上下文时,我的代码才会继续执行。我可以使用非阻塞版本 BeginGetContext() 和 EndGetContext()。当我想停止执行时,我使用取消 token 。
public void StartListening() {
_listener.Start();
_logger.LogDebug("Http Listening started");
Task.Run(() => {
while(true) {
if(_cancellationToken.IsCancellationRequested) return ;
try {
NonblockingListener();
}
catch (Exception e) {
_logger.LogError("Error With the listening Proccess, Message : "+e.Message);
}
}
},_cancellationToken);
}
public void StopListening() {
_cancellationTokenSource.Cancel();
ListenerCallback(null);
_logger.LogDebug("Http Listening Stop");
_listener.Close();
}
public void NonblockingListener() {
IAsyncResult result = _listener.BeginGetContext(ListenerCallback, _listener);
result.AsyncWaitHandle.WaitOne();
}
public void ListenerCallback(IAsyncResult result) {
if(_cancellationToken.IsCancellationRequested)return;
_listener = (HttpListener)result.AsyncState;
HttpListenerContext context = _listener.EndGetContext(result);
HttpListenerRequest request = context.Request;
//processing code
EnqueUrl(request);
}
关于c# - 无法访问已处置的对象。对象名称 : 'System.Net.HttpListener' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45183754/