c# - 无法访问已处置的对象。对象名称 : 'System.Net.HttpListener'

标签 c# .net asynchronous httplistener

我正在创建一个监听特定 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/

相关文章:

c# - app.xaml 资源字符串中的 XamlParseException

c# - 找不到类型或命名空间名称 'Skeleton'

c# - 在移动应用程序中使用 ApiController

c# - wpf保存图片的问题

mysql - 无法使用vb.net将数据插入Mysql

c# - 进程间 C# python 实时

c# - 在不指定 T 的情况下模拟 Moq 中的泛型方法

ios - 来自线程的 NSURLConnection 同步请求与异步请求

javascript - 用户离开页面后运行去抖函数

c# - 设置超时异步 Web 服务调用?