2017-07-19 49 views
0

我正在创建一个侦听特定Http请求的Windows服务。我在一个单独的任务中运行一个httpListener。当服务停止时,关闭侦听器实例。但似乎在HTTP listenerContext正在等待进入的请求,并为听众得到关闭,我得到以下错误无法访问处置的对象。对象名称:'System.Net.HttpListener'

Cannot access a disposed object. Object name: 'System.Net.HttpListener'. 

即使我使用一些机制来通知StartListening()倾听是停止了,它不会因为运行在相应的线程执行被阻止在HttpListenerContext context = await _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侦听器的合适方法。我使用的代码如下。 谢谢..

+0

,看一下这个问题https://stackoverflow.com/questions/16946389/stopping-and-restarting-httplistener – Ben

+0

谢谢@Ben,我还没有看到这篇文章,它提到使用'BeginGetContext( )'和'EndGetContext()',就像我在下面的答案中所做的那样 –

回答

0

我找到了解决方案。据我所知listener.GetContextAsync()是一种阻塞方法,并且只有当检测到新的上下文时,我的代码的执行才会继续。我可以使用非阻塞版本BeginGetContext()和EndGetContext()。当我想停止执行时,我使用取消令牌。

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); 
     } 
相关问题