2014-04-10 8 views
8

Wir haben einen selbst gehosteten SignalR-Server in unserer WPF-Anwendung. Die WebApp wird beim Start der Anwendung gestartet. Beim Application-Exit verfügen wir über die WebApp.Disposing Microsoft.Owin.Hosting.WebApp löst "System.ObjectDisposedException"

public void Start() 
    { 
     myWebApp = WebApp.Start<MyApp>(url); 
    } 

    private void Dispose(bool isDisposing) 
    { 
     if (disposed) return; 

     if (isDisposing) 
      myWebApp.Dispose(); 

     disposed = true; 
    } 

Der Aufruf von myWebApp.Dispose() stellt einen 'System.ObjectDisposedException'. Mache ich etwas falsch? . Die Microsoft.Owin * dlls haben die Version 2.1.0 und die SignalR Selbst Host 2.0.3

UPDATE: Stellt sich heraus, das ist die erste Chance, die ich in Visual Studio sehen können, weil die Einstellung „brechen auf clr Ausnahmen "ist aktiv. Diese Ausnahme scheint intern behandelt zu werden und springt nicht in unseren Code.

+0

Es kann die erste Chance in Ihrem Fall sein, aber wenn NLog Middleware verwendet wird: 'appBuilder.UseNLog()' protokolliert Ausnahme als Fehler. – SerG

Antwort

3

Nach der Untersuchung des Katana-Quellcodes habe ich einen Grund für dieses Problem gefunden. Es ist die Microsoft.Owin.Host.HttpListener.OwinHttpListener.ProcessRequestsAsync() Methode. Es beginnt While-Schleife mit _listener.GetContextAsync() Aufruf einer privaten HttpListener Instanz in Try-Catch-Abschnitt.

Auch Klasse implementiert IDisposable und enthält eine Dispose() Methode. Diese Methode verfügt über die private Instanz HttpListener.

Wenn Sie anrufen WebApp.Start() es gibt eine Instanz von IDisposable, dass nur Dispose() Methode hat, die OwinHttpListener verfügt.

Also, wenn Sie es entsorgen, rufen Sie seine Dispose() Methode OwinHttpListener, die die private HttpListener verfügt.

Aber zugleich ProcessRequestsAsync() Anrufe _listener.GetContextAsync(), aber _listener ist bereits angeordnet und wirft ObjectDisposedException. catch Block protokolliert die Ausnahme und kehrt von ProcessRequestsAsync() zurück.

Ich denke, dass Doppel-Check-Sperre in ProcessRequestsAsync() eine gute Option sein kann.

+0

Also gibt es keine Möglichkeit, das Problem zu beheben, ohne Katana neu zu schreiben. Ist es richtig? – SerG

+1

@SerG ja, ist es. Alles, was Sie tun können, ist das Objekt leave, das von WebApp.Start(), dispositioniert zurückgegeben wird. – Tim

+0

Ich bin mir nicht sicher, wo doppeltes Sperren hier helfen würde. Es scheint jedoch, dass die Dispose-Methode mehr tun muss, um den asynchronen Prozess herunterzufahren, der immer noch versucht, Dinge zu tun, während der Listener darunter abgelegt wird. –

Verwandte Themen