7 Stimmen

Xml-Serialisierung ohne Disposing

       using (var file_stream = File.Create("users.xml"))
        {
            var serializer = new XmlSerializer(typeof(PasswordManager));
            serializer.Serialize(file_stream, this);
            file_stream.Close();
        }

Die Verwendung des obigen Codes funktioniert perfekt. Allerdings, wenn ich es zu verkürzen:

          var serializer = new XmlSerializer(typeof(PasswordManager));
          serializer.Serialize(File.Create("users.xml"), this);

Ich erhalte die folgende Ausnahme, wenn ich versuche, die Datei users.xml im selben Test zu deserialisieren: Der Prozess kann nicht auf die Datei 'users.xml' zugreifen, da sie von einem anderen Prozess verwendet wird.

Die Ursache scheint zu sein, dass die File.Create-Methode einen geöffneten FileStream zurückgibt, den ich nicht schließen kann, da ich keinen Verweis darauf behalte.

Mein Fehler, oder der von Microsoft? ;-)

12voto

Darin Dimitrov Punkte 990883

Das Problem ist, dass Sie in Ihrem zweiten Beispiel ein Dateihandle öffnen, das Sie nie entsorgen, so dass beim zweiten Aufruf Ihrer Methode die von Ihnen beschriebene Ausnahme ausgelöst wird. Das erste Snippet ist der bessere Weg (Sie könnten das file_stream.Close() Bit entfernen - es wird automatisch von Stream.Dispose() aufgerufen).

2voto

anonymous Punkte 645

Sie sollten die Serialisierung in einer endlich versuchen Block, so dass Sie sicherstellen können, dass die Datei unabhängig von Erfolg oder Misserfolg geschlossen/entsorgt wird. Das ist es, was der mit Schlüsselwort für Sie tut.

var serializer = new XmlSerializer(typeof(PasswordManager));
var fs = File.Create("users.xml");
try { serializer.Serialize(fs,this); }
finally { fs.Close(); }

0voto

Nader Shirazie Punkte 10691

Wenn Sie die "using"-Anweisung weggelassen, aber den Abschluss beibehalten hätten, wäre das in Ordnung gewesen.

[Bearbeiten: Versuch hinzugefügt...endlich, danke Cheeso]

var serializer = new XmlSerializer(typeof(PasswordManager));
FileStream fs;
try
{
    fs = File.Create("users.xml");
    serializer.Serialize(fs, this);
}
finally
{
    fs.Close(); // or fs.Dispose()
}

In diesem Fall ist Dispose jedoch vorzuziehen, weil es weiß alle die Maßnahmen, die er ergreifen muss, um aufzuräumen, einschließlich der Schließung (und aller anderen Dinge).

0voto

anonymous Punkte 645

File.Create sollte außerhalb des Try-Blocks platziert werden, wie in meiner früheren Antwort gezeigt. Wenn Sie es innerhalb des try-Blocks platzieren, müssen Sie prüfen fs für eine Null-Referenz vor dem Schließen. Im Folgenden wird der korrigierte Code gezeigt, aber meine erste Antwort ist viel besser, da Sie diese Prüfung vermeiden können.

serializer = new XmlSerializer(typeof(PasswordManager));
FileStream fs;
try
{
    fs = File.Create("users.xml");
    serializer.Serialize(fs, this);
}
finally
{
    if (fs != null)  // in case File.Create fails
        fs.Close(); // or fs.Dispose()
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X