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?
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.
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.
Implementieren Sie IDisposable (Sie sollten dies tun, wenn Sie das Feld Disposable haben). Schließen Sie Srv_LoginChannelFactory nicht mit Ausnahme von Login.Dispose.
Ä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?)
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%Tags und Links wcf c# objectdisposedexception