Was könnte in WCF den Fehler "Kann nicht auf ein disponiertes Objekt zugreifen" verursachen?

8

Ich verwende den folgenden Code:

%Vor%

Das Login ist mein Konstruktor:

%Vor%

Und ich benutze Service auf diese Weise:

%Vor%

Wenn der Benutzer einen gültigen Benutzernamen und ein Passwort eingibt, ist alles in Ordnung. Wenn der Benutzer einen falschen Benutzernamen und ein falsches Passwort eingibt, wird beim ersten Versuch die Meldung "Nicht eingegeben" angezeigt. Beim zweiten Versuch sieht der Benutzer diese Meldung:

%Vor%

Wie kann ich meinen Code reparieren, um diesen Fehler zu vermeiden?

    
Arian 01.01.2011, 08:13
quelle

2 Antworten

12

Srv_LoginChannelFactory.Close() ist der Ort, an dem es entsorgt wird. Wenn Sie schließen, geben Sie Ihre nicht gemanagte Ressource auf. Wenn Sie versuchen, etwas anderes zu tun, als den Status zu prüfen oder erneut zu öffnen, wird die Ausnahme "Kann auf ein vorhandenes Objekt nicht zugreifen" zurückgegeben.

Dies gilt immer dann, wenn Sie ein Einwegobjekt schließen und danach versuchen, etwas damit zu tun. Zum Beispiel Schreiben in eine Datei, die geschlossen ist, oder Ausführen einer SQL-Anweisung für eine geschlossene Datenbankverbindung.

Um das anzugehen, haben Sie drei Möglichkeiten.

  1. Machen Sie die Srv_LoginChannelFactory nicht zu einem Feld. Stattdessen machen Sie es lokal zum Klicken auf die Schaltfläche. Wenn dies der einzige Ort ist, an dem Sie es verwenden, ist dies wahrscheinlich sinnvoll, da es die Zeit verkürzt, die Sie mit einer nicht verwalteten Ressource verbringen.

  2. Implementieren Sie IDisposable (Sie sollten dies tun, wenn Sie das Feld Disposable haben). Schließen Sie Srv_LoginChannelFactory nicht mit Ausnahme von Login.Dispose.

  3. Ändern Sie die Schaltfläche, um den Status von Srv_LoginChannelFactory zu überprüfen, bevor Sie versuchen, einen Kanal damit zu erstellen. Sie müssen IDisposable dennoch implementieren, wenn der Klick auf die Schaltfläche nicht erfolgt.

Hinweis : EnsureOpened sieht so aus, als könnte es verwendet werden, um den Status zu überprüfen, aber es funktioniert nur, bevor es geöffnet wird. Sobald es geschlossen wurde, wird es werfen.

In Bezug auf Close () ist dasselbe wie Dispose.

Aus dem Abschnitt "Anpassen eines Dispose-Methodennamens" in Implementierung finalisieren und disponentieren, um nicht verwaltete Ressourcen zu bereinigen in den Designrichtlinien für die Entwicklung von Klassenbibliotheken

  

Gelegentlich ist ein domänenspezifischer Name   passender als Dispose. Zum   Beispiel könnte eine Dateikapselung sein   möchte den Methodennamen Close verwenden. Im   In diesem Fall implementieren Sie Dispose privat   und erstellen Sie eine öffentliche Close-Methode, die   Anrufe Dispose. Der folgende Code   Beispiel veranschaulicht dieses Muster. Sie   kann Schließen mit einem Methodennamen ersetzen   passend zu Ihrer Domain. Dies   Beispiel erfordert den System-Namespace.

Die Idee hier ist, der Open-Methode Parität zu geben. Persönlich denke ich, dass es eine Menge Verwirrung verursacht, aber ich kann mir nichts besseres vorstellen (CloseAndDispose?)

    
Conrad Frix 01.01.2011, 08:33
quelle
2

Das Problem hier (was Conrad meiner Meinung nach verpasst hat) ist, dass Kerezo die ChannelFactory (Srv_LoginChannelFactory) schließt, die alle seine Kanäle schließt, wenn er wahrscheinlich nur den Channel (LoginService) schließen will.

Also ändern:

%Vor%

zu:

%Vor%     
Nick Westgate 14.11.2013 03:41
quelle

Tags und Links