1

我在 Windows 服务中使用 HttpListener 实现了一个非常简单的 C# Http Server,它等待请求并在收到请求时将它们发送到 ZMQ。它与这里的 HTTP 服务器非常相似 -生产就绪、多线程 c# http 服务器,只是它异步执行 RunServer 委托,然后一旦服务启动,就会处于 HttpListener 正在侦听的连续循环中。我想我有一些大部分工作的东西,但是当我停止服务器时,如果请求未完成,那么它会引发错误

由于线程退出或应用程序请求,I/O 操作已中止

在处理方法中。我担心我也忽略了生产环境所需的其他东西。

    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();
    }
4

1 回答 1

3

通过“停止服务器”,我假设您的意思是您正在代码中调用 Stop() 方法。这是调用侦听器的 Close() 方法,这会使任何挂起的请求无法完成 (http://msdn.microsoft.com/en-us/library/system.net.httplistener.close.aspx)。

您应该首先调用侦听器的 Stop() 方法,等到所有挂起的请求都已处理完毕,然后再调用 Close()。

除非您的应用程序允许切断这些待处理的请求,在这种情况下,您可以接受并忽略错误,但一般来说,最好让它们完成以避免您半处理的情况请求并且客户端重新提交它。

于 2012-02-20T16:12:15.887 回答