Destruktor, Dispose und Strams schließen

17/02/2010 - 22:05 von René | Report spam
Dies ist eine mehrteilige Nachricht im MIME-Format.

=_NextPart_000_0059_01CAB01D.46845BE0

Hallo,

ich bin relativ neu, was C# angeht. Ich komme aus der C++-Ecke und es fàllt mir manchmal schwer, mir einige Dinge abzugewöhnen.

Nun entdecke ich Tag für Tag die Vorteile der Sprache, des Frameworks und der Entwicklungsumgebung. Jetzt verstehe ich auch all diejenigen, die mir immer wieder den Wechsel von C++ auf C# nahe legten. Trotzdem habe ich ein Problem, welches ich mir nicht richtig erklàren kann.

In einer Klasse öffne ich (hier stark vereinfacht) zwei Dateien:

StreamReader srSPL = new StreamReader(new FileStream(sFileSPL, FileMode.Open, FileAccess.Read, FileShare.None), System.Text.Encoding.Default);
StreamWriter swPCL = new StreamWriter(new FileStream(sFilePCL, FileMode.Open, FileAccess.Write, FileShare.None), System.Text.Encoding.Default);

Ich lese aus srSPL zeilenweise ein, verarbeite ich diese Zeilen und schreibe lege sie in srPCL auch zeilenweise ab. Funktioniert auch ohne Probleme.

Im Destruktor bzw. in der Dispose-Methode möchte ich diese Dateien, sofern vorhanden, löschen. Dazu sollten sie nach meinem Verstàndnis zunàchst geschlossen werden, um sie danach zu löschen. Daher schließe ich diese Dateien und lösche ich sie danach:

class SPL2PDF : IDisposable
{
.
.
.

~SPL2PDF()
{
Dispose(false);
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// nichts tun.
}
srSPL.Close();
swPCL.Close(); // <<<<<<FEHLER>>>>>>
}
}
disposed = true;
.
.
.
}


.
.
.
}

Und genau an der markierten Stelle wird eine Ausnahme geworfen, obwohl ich die Datei nicht geschlossen habe. Der Fehler ("Auf eine geschlossene Datei kann nicht zugegriffen werden.") ist reproduzierbar und lautet:

System.ObjectDisposedException wurde nicht behandelt.
Message=Auf eine geschlossene Datei kann nicht zugegriffen werden.
Source=mscorlib
ObjectName=""
StackTrace:
bei System.IO.__Error.FileNotOpen()
bei System.IO.FileStream.Write(Byte[] array, Int32 offset, Int32 count)
bei System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
bei System.IO.StreamWriter.Dispose(Boolean disposing)
bei System.IO.StreamWriter.Close()
bei ise.SPL2PDF.Dispose(Boolean disposing)
bei ise.SPL2PDF.Finalize()
InnerException:

Das Schließen der ersten Datei ("srSPL") schlàgt dagegen nie fehl.

Woran liegt das Problem?

Bin für jede Hilfe dankbar!

Umgebung:
Windows 7 Ultimate 32 Bit
Visual Studio Pro 2010 Beta 2
=_NextPart_000_0059_01CAB01D.46845BE0

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=text/html;charset=iso-8859-1 http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.7600.16490"></HEAD>
<BODY style="PADDING-LEFT: 10px; PADDING-RIGHT: 10px; PADDING-TOP: 15px"
id=MailContainerBody leftMargin=0 topMargin=0 CanvasTabStop="true"
name="Compose message area">
<DIV><FONT size=2 face=Consolas>Hallo,<BR><BR>ich bin relativ neu, was C#
angeht. Ich komme aus der C++-Ecke und es fàllt mir manchmal schwer, mir einige
Dinge abzugewöhnen.<BR><BR>Nun entdecke ich Tag für Tag die Vorteile der
Sprache, des Frameworks und der Entwicklungsumgebung. Jetzt verstehe ich auch
all diejenigen, die mir immer wieder den Wechsel von C++ auf C# nahe legten.
Trotzdem habe ich ein Problem, welches ich mir nicht richtig erklàren
kann.<BR><BR>In einer Klasse öffne ich (hier stark vereinfacht) zwei
Dateien:</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT>&nbsp;</DIV>
<DIV><FONT size=2 face=Consolas>StreamReader srSPL = new StreamReader(new
FileStream(sFileSPL, FileMode.Open, FileAccess.Read, FileShare.None),
System.Text.Encoding.Default);</FONT></DIV>
<DIV><FONT size=2 face=Consolas>StreamWriter swPCL = new StreamWriter(new
FileStream(sFilePCL, FileMode.Open, FileAccess.Write, FileShare.None),
System.Text.Encoding.Default);</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT>&nbsp;</DIV>
<DIV><FONT size=2 face=Consolas>Ich lese aus srSPL zeilenweise ein, verarbeite
ich diese Zeilen und schreibe lege sie in srPCL auch zeilenweise ab.
Funktioniert auch ohne Probleme.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT>&nbsp;</DIV>
<DIV><FONT size=2 face=Consolas>Im Destruktor bzw. in der Dispose-Methode möchte
ich diese Dateien, sofern vorhanden, löschen. Dazu sollten sie nach meinem
Verstàndnis zunàchst geschlossen werden, um sie danach zu löschen. Daher
schließe ich diese Dateien und lösche ich sie danach:</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT>&nbsp;</DIV>
<DIV><FONT size=2 face=Consolas>class SPL2PDF : IDisposable</FONT></DIV>
<DIV>
<DIV><FONT size=2 face=Consolas>{</FONT></DIV>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;.</FONT></DIV>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;.</FONT>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT>&nbsp;</DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;~SPL2PDF()</FONT></DIV></DIV></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dispose(false);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT>&nbsp;</DIV>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;public void
Dispose()</FONT></DIV>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;{</FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dispose(true);</FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GC.SuppressFinalize(this);</FONT></DIV>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></DIV>
<DIV><FONT face=Calibri></FONT><FONT face=Calibri></FONT><BR><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;protected void Dispose(bool
disposing)</FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if
(!disposed)</FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if
(disposing)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
nichts
tun.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;srSPL.Close();</FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT
color=#ff0000><STRONG>swPCL.Close();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
&lt;&lt;&lt;&lt;&lt;&lt;FEHLER&gt;&gt;&gt;&gt;&gt;&gt;</STRONG></FONT></FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;disposed =
true;</FONT></DIV>
<DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</FONT></DIV>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;. </FONT>
<DIV><FONT size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</FONT></DIV>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<DIV><FONT size=2 face=Consolas></FONT>&nbsp;</DIV>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;.</FONT></DIV>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;.</FONT> </DIV>
<DIV><FONT size=2 face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;.</FONT></DIV>
<DIV>}</DIV>
<DIV><FONT color=#00bdce></FONT>&nbsp;</DIV>
<DIV><FONT color=#000000>Und genau an der markierten Stelle wird eine Ausnahme
geworfen, obwohl ich die Datei nicht geschlossen habe. Der Fehler ("Auf eine
geschlossene Datei kann nicht zugegriffen werden.") ist reproduzierbar und
lautet:</FONT></DIV>
<DIV><FONT color=#00bdce></FONT>&nbsp;</DIV>
<DIV><FONT color=#00bdce>System.ObjectDisposedException wurde nicht
behandelt.<BR>&nbsp; Message=Auf eine geschlossene Datei kann nicht zugegriffen
werden.<BR>&nbsp; Source=mscorlib<BR>&nbsp; ObjectName=""<BR>&nbsp;
StackTrace:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bei
System.IO.__Error.FileNotOpen()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bei
System.IO.FileStream.Write(Byte[] array, Int32 offset, Int32
count)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bei
System.IO.StreamWriter.Flush(Boolean flushStream, Boolean
flushEncoder)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bei
System.IO.StreamWriter.Dispose(Boolean
disposing)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bei
System.IO.StreamWriter.Close()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bei
ise.SPL2PDF.Dispose(Boolean disposing)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
bei ise.SPL2PDF.Finalize()<BR>&nbsp; InnerException: <BR></FONT></DIV>
<DIV><FONT color=#00bdce><FONT color=#000000>Das Schließen der ersten Datei
("srSPL") schlàgt dagegen nie fehl.</FONT></FONT></DIV>
<DIV><FONT color=#00bdce><FONT color=#000000></FONT></FONT>&nbsp;</DIV>
<DIV><FONT color=#00bdce><FONT color=#000000>Woran liegt das
Problem?</FONT></FONT></DIV>
<DIV><FONT color=#00bdce><FONT color=#000000></FONT></FONT>&nbsp;</DIV>
<DIV><FONT color=#00bdce><FONT color=#000000>Bin für jede Hilfe
dankbar!</FONT></FONT></DIV>
<DIV><FONT color=#00bdce><FONT color=#00bdce></FONT></FONT>&nbsp;</DIV>
<DIV><FONT color=#000000><STRONG>Umgebung:</STRONG></FONT></DIV>
<DIV><FONT color=#00bdce><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;Windows 7
Ultimate 32 Bit</FONT></FONT></DIV>
<DIV><FONT color=#00bdce><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;Visual
Studio Pro 2010 Beta
2</FONT></DIV></FONT></FONT></DIV></DIV></DIV></BODY></HTML>

=_NextPart_000_0059_01CAB01D.46845BE0--
 

Lesen sie die antworten

#1 René
17/02/2010 - 22:15 | Warnen spam
Dies ist eine mehrteilige Nachricht im MIME-Format.

=_NextPart_000_0067_01CAB01E.C5C6FBA0

Die geschweifte Klammer (sieh unten) ist nur ein Tippfehler:

protected void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// nichts tun.
}
srSPL.Close();
swPCL.Close(); // <<<<<<FEHLER>>>>>>
// } <<< Diese Klammer ist nur ein Tippfehler!
}
disposed = true;
.
.
.
}


=_NextPart_000_0067_01CAB01E.C5C6FBA0

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=text/html;charset=iso-8859-1 http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.7600.16490"></HEAD>
<BODY style="PADDING-LEFT: 10px; PADDING-RIGHT: 10px; PADDING-TOP: 15px"
id=MailContainerBody leftMargin=0 topMargin=0 CanvasTabStop="true"
name="Compose message area">
<DIV><FONT size=2 face=Consolas><FONT color=#00bdce><FONT color=#000000>Die
geschweifte Klammer (sieh unten) ist nur ein
Tippfehler:</FONT></FONT></FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT>&nbsp;</DIV>
<DIV><FONT size=2 face=Consolas><FONT color=#00bdce><FONT
color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;protected void Dispose(bool
disposing)</FONT>
<DIV><FONT color=#000000 size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if
(!disposed)</FONT></DIV>
<DIV><FONT color=#000000 size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if
(disposing)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</FONT></DIV>
<DIV><FONT color=#000000 size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
nichts
tun.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;srSPL.Close();</FONT></DIV>
<DIV><FONT size=2 face=Consolas><FONT
color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>swPCL.Close();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
&lt;&lt;&lt;&lt;&lt;&lt;FEHLER&gt;&gt;&gt;&gt;&gt;&gt;</STRONG></FONT></FONT></DIV>
<DIV><FONT color=#339966 size=2
face=Consolas><STRONG>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;
&lt;&lt;&lt; Diese Klammer ist nur ein Tippfehler!</STRONG></FONT></DIV>
<DIV><FONT color=#000000 size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></DIV>
<DIV><FONT color=#000000 size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;disposed =
true;</FONT></DIV>
<DIV>
<DIV><FONT color=#000000 size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</FONT></DIV>
<DIV><FONT color=#000000 size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;. </FONT>
<DIV><FONT color=#000000 size=2
face=Consolas>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</FONT></DIV>
<DIV><FONT size=2 face=Consolas><FONT
color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;}<BR></FONT>
<DIV><FONT size=2 face=Consolas></FONT><FONT
color=#000000></FONT>&nbsp;</DIV></FONT></DIV></DIV></DIV></DIV></FONT></FONT></BODY></HTML>

=_NextPart_000_0067_01CAB01E.C5C6FBA0--

Ähnliche fragen