Question

I am using a HttpListener and using BeginGetContext to get my context object. I want to cleanly shut down my HttpListener but if I attempt to do a Close on the listener I get a exception and it causes my program to exit.

using System;
using System.Net;

namespace Sandbox_Console
{
    class Program
    {
        public static void Main()
        {
            if (!HttpListener.IsSupported)
            {
                Console.WriteLine("Windows XP SP2 or Server 2003 is required to use the HttpListener class.");
                return;
            }

            // Create a listener.
            HttpListener listener = new HttpListener();
            listener.Prefixes.Add("http://vwdev.vw.local:8081/BitsTest/");
            listener.Start();
            Console.WriteLine("Listening...");

            listener.BeginGetContext(Context, listener);
            Console.ReadLine();

            listener.Close(); //Exception on this line, but not shown in Visual Studio
            Console.WriteLine("Stopped Listening..."); //This line is never reached.
            Console.ReadLine();

        }

        static void Context(IAsyncResult result)
        {
            HttpListener listener = (HttpListener)result.AsyncState;
            HttpListenerContext context = listener.EndGetContext(result);

            context.Response.Close();
            listener.BeginGetContext(Context, listener);
        }
    }
}

The program throws a exception on the listener.Close() however the error never gets shown in Visual Studio, the only note I get is the following in the Debug output screen:

A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll
The program '[2568] Sandbox Console.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).

I was able to get the real execption from windows Event Viewer

Application: Sandbox Console.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.ObjectDisposedException
Stack:
   at System.Net.HttpListener.EndGetContext(System.IAsyncResult)
   at Sandbox_Console.Program.Context(System.IAsyncResult)
   at System.Net.LazyAsyncResult.Complete(IntPtr)
   at System.Net.ListenerAsyncResult.WaitCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)

What do I need to do so I can close my HttpListener cleanly?

Was it helpful?

Solution

Context gets called one last time when you call Close, you must handle the object disposed exception that could get thrown

static void Context(IAsyncResult result)
{
    HttpListener listener = (HttpListener)result.AsyncState;

   try
   {
        //If we are not listening this line throws a ObjectDisposedException.
        HttpListenerContext context = listener.EndGetContext(result);

        context.Response.Close();
        listener.BeginGetContext(Context, listener);
   }
   catch (ObjectDisposedException)
   {
       //Intentionally not doing anything with the exception.
   }
}

OTHER TIPS

You could add this line

if (!listener.IsListening) { return; }
HttpListenerContext context = listener.EndGetContext(ctx);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top