2012-11-12 5 views
8

Ich verwende eine HttpListener und BeginGetContext verwenden, um mein Kontextobjekt zu erhalten. Ich möchte meinen HttpListener sauber herunterfahren, aber wenn ich versuche, einen Close auf dem Listener zu machen, erhalte ich eine Ausnahme und es bewirkt, dass mein Programm beendet wird.Reinigen Sie die BeginGetContext-Methode von HttpListener sauber

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

Das Programm wirft eine Ausnahme auf dem listener.Close() jedoch der Fehler nie in Visual Studio gezeigt wird, ist der einzige Note, die ich erhalten, ist die folgende in dem Testausgabebildschirm:

Eine erste Chance Ausnahme von Typ 'System.ObjectDisposedException' in System.dll aufgetreten
Das Programm '[2568] Sandbox Console.vshost.exe: Managed (v4.0.30319)' wurde mit Code 0 (0x0) beendet.

konnte ich die echte execption von Windows-Ereignisanzeige

 
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*) 

Was ich schließe ich meine Httplistener sauber kann so tun müssen, bekommen?

+0

So Ihre async 'static void hinzufügen könnte geworfen bekommen könnte Kontext wird niemals aufgerufen? .. etwas ist schief gelaufen .. 'ObjectDisposedException's werden geworfen, wenn Sie versuchen, ein Objekt zu entsorgen, das bereits entsorgt wurde. Etwas sagt mir, dass die Initialisierung Ihres Zuhörers kaputt ist. –

+0

@SimonWhitehead AH AH! Der Kontext wird ein letztes Mal aufgerufen, wenn Sie Close aufrufen. Eine Lösung aufschreiben. –

Antwort

13

Kontext wird ein letztes Mal aufgerufen, wenn Sie Schließen rufen Sie das Objekt angeordnet Ausnahme behandeln müssen, die

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

Dies ist fehlerhaft, weil dadurch möglicherweise legitime Kontexte verloren gehen. – usr

+0

Was würden Sie empfehlen, um es zu lösen? –

+0

Die einzige Möglichkeit, einen Listener zu schließen, den ich kenne, ist, die Ausnahme zu fangen und zu behandeln ... ekelhaftes API-Problem. Genau wie mit Steckdosen. – usr

0

Sie diese Zeile

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

Eigentlich, wenn Sie sich die Revisionshistorie meiner Antwort ansehen, ist das genau das, was mein Code getan hat, und usr hat darauf hingewiesen, dass dies dazu führen kann, dass legitime Kontexte verloren gehen und ich meine Antwort auf den aktuellen Weg aktualisierte. –

Verwandte Themen