Question

I have implemented a really simple C# Http Server using HttpListener within a windows service, that waits for requests and sends them to a ZMQ when recieved. It is very similar to the HTTP server here - Production ready, multi-threaded c# http server except it executes the RunServer delegate asynchronously and then once the service has started sits in a continuous loop whist the HttpListener is listening. I think I have something which works in most part, however when I stop the server if requests are outstanding then it throws an error

The I/O operation has been aborted because of either a thread exit or an application request

in the Handle method. I'm worried I'm overlooking other things too which would be needed for a production environment.

    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();
    }
Was it helpful?

Solution

By "stop the server", I assume you mean you're calling the Stop() method in your code. This is calling the listener's Close() method, which leaves any pending requests unable to complete (http://msdn.microsoft.com/en-us/library/system.net.httplistener.close.aspx).

You should first call the listener's Stop() method, wait until all pending requests have been handled, and then Close() it.

Unless your application makes it okay to chop off those pending requests, in which case you could just accept and ignore the error, but, in general, it would likely be best to let them finish to avoid situations where you've half-processed a request and the client resubmits it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top