2017-07-19 73 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); 
     } 
相關問題