2012-02-17 50 views
1

我已經在Windows服務中使用HttpListener實現了一個非常簡單的C#Http服務器,它等待請求並在接收時將它們發送給ZMQ。它與HTTP服務器非常相似 - Production ready, multi-threaded c# http server,不同之處在於它異步執行RunServer委託,然後一旦服務啓動後,HttpListener正在監聽的連續循環中。我覺得我有一些東西,在大多數情況下工作,但是當我停止服務器,如果請求是突出的,然後它拋出一個錯誤簡單的Http服務器在生產中的HttpListener

的I/O操作已中止,因爲線程退出或 的應用要求

在Handle方法中。我擔心我忽視了生產環境所需的其他事情。

public XsmHttpServer(string httpAddressEndpoint) 
    {       
     _listener = new HttpListener(); 
     _listenerAddr = httpAddressEndpoint; 
    } 

    public void Start() 
    { 
     _listener.Start(); 

     Action action = RunServer; 
     action.BeginInvoke(RunServerCallback, action);       
    } 


    private void RunServer() 
    { 
     while (_listener.IsListening) 
     { 
      IAsyncResult result = _listener.BeginGetContext(Handle, _listener); 
      result.AsyncWaitHandle.WaitOne(); 
     } 
    } 


    private void Handle(IAsyncResult result) 
    { 
     HttpListener listener = (HttpListener)result.AsyncState; 
     HttpListenerContext context = listener.EndGetContext(result); 

     //Do work, send to ZMQ & write response back 
     _handler.Handle(context);           
    } 

    private void RunServerCallback(IAsyncResult ar) 
    { 
     try 
     { 
      Action target = (Action)ar.AsyncState; 
      target.EndInvoke(ar); 
     } 
     catch (Exception ex) 
     { 
      if (_log.IsDebugEnabled) _log.Debug("Failed to initialize Server", ex); 
     } 
    } 


    public void Stop() 
    { 
     _listener.Close(); 
    } 

回答

3

通過「停止服務器」,我假設你的意思是你在代碼中調用Stop()方法。這是調用偵聽器的Close()方法,這會導致任何掛起的請求無法完成(http://msdn.microsoft.com/zh-cn/library/system.net.httplistener.close.aspx)。

您應該先調用偵聽器的Stop()方法,等待所有待處理的請求都已處理,然後再關閉()它。

除非你的應用程序能夠切斷那些未決的請求,在這種情況下,你可以接受並忽略錯誤,但是,一般情況下,最好讓它們完成以避免出現問題半處理一個請求,客戶端重新提交。

+0

謝謝 - 我會將此添加到我的代碼中 – Nicki 2012-03-02 10:36:24