2012-11-12 15 views
8

Używam HttpListener i używam BeginGetContext do pobierania obiektu kontekstowego. Chcę wyczyścić mój HttpListener, ale jeśli spróbuję zrobić Close na odbiorniku, otrzymuję wyjątek i powoduje to, że mój program zostanie zamknięty.Wyczyść przerwanie metody BeginGetContext HttpListenera

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

Program zgłasza wyjątek na listener.Close() jednak nigdy błędu zostanie pokazany w Visual Studio, jedyna uwaga mam jest następujący na ekranie wyjścia Debug:

Pierwsza szansa wyjątkiem typ "System.ObjectDisposedException" wystąpił w System.dll
Program "[2568] Sandbox Console.vshost.exe: Managed (v4.0.30319)" zakończył działanie z kodem 0 (0x0).

udało mi się dostać prawdziwą execption z systemu 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*) 

Co muszę zrobić, więc może zamknę HttpListener czysto?

+0

więc asynchronicznej 'static void Kontekst "nigdy nie zostanie wywołany? ... coś poszło nie tak ... 'ObjectDisposedException's są zgłaszane przy próbie pozbycia się obiektu, który jest już usunięty. Coś mi mówi, że inicjalizacja twojego słuchacza jest zepsuta. –

+0

@ SimonWhitehead AH AH! Kontekst zostanie wywołany po raz ostatni, gdy zadzwonisz Close. Pisanie rozwiązania. –

Odpowiedz

13

Kontekst jest wywoływana po raz ostatni podczas rozmowy Zamknij, musi obsługiwać obiekt wyrzucać wyjątek, który mógłby trafiają

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. 
    } 
} 
+0

To jest uszkodzone, ponieważ może to spowodować utratę uzasadnionych kontekstów. – usr

+0

Co byś polecił, aby go rozwiązać? –

+0

Jedynym sposobem na wyłączenie słuchacza, o którym wiem, jest złapanie i obsługiwanie wyjątku ... obrzydliwego problemu z interfejsem API. Podobnie jak z gniazdkami. – usr

0

Można dodać linię

if (!listener.IsListening) { return; } 
HttpListenerContext context = listener.EndGetContext(ctx); 
+0

Właściwie, jeśli spojrzysz na historię zmian mojej odpowiedzi, to jest dokładnie to, co robił mój kod, a usr wskazywał, że zrobienie tego może spowodować utratę uzasadnionych kontekstów i zaktualizowałem swoją odpowiedź na obecny sposób. –