Closed TextWriter

My app reads multiple files and creates a temp text file which contains from 100,000 to 200,000 records. After the file is creates, it then reads the newly created text file and processes the records that were extracted and writes them to a permanent output file..

The problem I'm encountering is that the app writes the first record and proceeds to the next record in the file, processes and processes it successfully, however; when it tries to write this record, it abends with this error message:

System.ObjectDisposedException: Cannot write to a closed TextWriter.
at System.IO.__Error.WriterClosed()
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.Write(Char[] buffer, Int32 index, Int32count)
at System.IO.TextWriter.WriteLine(String value)
at DOHRecordConversion.FormDOHRecordConvert.ProcessFiles(String file) in
c:\projects\doh\dohrecordconversion\formdohrecordconvert,cs:line 1192

Normally, I can understand this, but this time, I am thoroughly confused because I can't find where the file is being closed. I've added the code below and as you can see, I don't close the file until the while loop is done.

private void ProcessFiles( string file )
{
string strInputText = null;
string strRecLen = "";

ResetButtons( "convert" );
m_inFilePath = m_strTestTempFile;
FileInfo dohFileIn = new FileInfo( m_inFilePath );
StreamReader sr_inStream = dohFileIn.OpenText();

try
{
using( sr_inStream )
{
while ( ( strInputText = sr_inStream.ReadLine() ) != null )
{
strRecLen = strInputText.Length.ToString();
strInputText = ProcessDOHrecord(strInputText);
using ( sw_dohDeathWriter )
{
sw_dohDeathWriter.WriteLine( strInputText ); <== The error occurs here
System.Windows.Forms.Application.DoEvents();
m_dblSummaryCount++;
labelCurrentStatus.Text = m_dblSummaryCount.ToString( ("##,###,###") );
}
}
sr_inStream.Close();
sw_dohDeathWriter.Close();
File.Delete( m_strTestTempFile );
}

catch (IOException ex)
{
MessageBox.Show ( "I/O error occured attempting to Convert this record:\n\n" +
strInputText.ToString() + "\n\n" +
ex.ToString(),
"Open/Read Error"

buttonOk,
errorIcon );
this.Close();
}

catch ( ArgumentOutOfRangeException ax )
{
MessageBox.Show ( "Argument Out of Range error " +
strInputText.ToString() + "\n\n" +
ax.ToString(),
"Open/Read Error",
buttonOk,
errorIcon );
this.Close();
}
catch (Exception ex)
{
MessageBox.Show ( "Unknown error occured attempting to Convert this record:\n\n " +
trInputText.ToString() + "\n\n" +
ex.ToString(),
caption,
buttonOk,
errorIcon );
this.Close();
}

ResetButtons( "idle" );

} //* end method: buttonConvertRecords_Click

private string ProcessDOHrecord(string strInputText)
{
string strHoldDoh = " ";
int intRecLen = 0;
int intOutLen = 0;
string strRecLen = comboBoxRecordLength.Text.Substring(0,3);
string errMsg = "occured while attempting to process this file ";
string errCaption = "IO Error - Process DOH File";

StringBuilder strTempText = new StringBuilder( strInputText );

try
{
switch (strRecLen)
{
//* Decedant Name List
case "210":
m_strOutputPath += m_strProdFtp520NAMELIST;
break;
//* Death Event List
case "212"
m_strOutputPath += m_strProdFtp520EVENTLIST;
break;
}
}
catch(IOException ioex)
{
string ioexCaption = " File Conversion Error";
string message1 = "End Of File reached. ";
string message2 = "\nRecords Processed...: ";

// Display the MessageBox.
MessageBox.Show (message1 +
message2 + "\n\n" +
ioex.ToString(),
ioexCaption,
buttonOk,
errorIcon);
}
return strInputText;
}

private void OpenOutputFile(string strFileType)
{
string message = "occured attempting to open this output file: \n\n ";
string caption = "Open/Read Error";

m_strOutputPath = m_strProdFileBeginPath;
if ( !checkboxTesting.Checked )
{
m_strOutputPath += m_strDohPath;
}
else
{
m_strOutputPath += m_strDohTestPath;
}

try
{
sw_dohDeathWriter = new StreamWriter( m_strOutputPath, true );
}
catch( IOException iox )
{
MessageBox.Show ( "I/O error " + message +
m_strOutputPath.ToString() + "\n\n" +
iox.ToString(),
caption,
buttonOk,
errorIcon );
}
}




Answer this question

Closed TextWriter

  • Tan0717

    The problem lies with your use of the using statement. This statement is used to ensure that IDisposable.Dispose is called when the block goes out of scope. Calling Dispose() on a TextWriter (or a Stream) is equivalent to calling Close().

    So effectively, your using( sw_dohDeathWriter) statement is closing the writer after the first iteration through the loop (right after you update labelCurrentStatus).



  • Boman

    ARRRRRGH!

    That was too obvious. All I had to do was remove the braces from the inside of the while statement.

    Thank you both for the "mind jog". I had stared at that code for that last couple of days thinking the file was being closed in another method!



  • Scott Boyd

    As you know, you are closing your stream twice... however only one of those closes is explicit.

    Whenever you use the using statement as you do below:

    using ( sw_dohDeathWriter )
    {
    sw_dohDeathWriter.WriteLine( strInputText ); <== The error occurs here
    System.Windows.Forms.Application.DoEvents();
    m_dblSummaryCount++;
    labelCurrentStatus.Text = m_dblSummaryCount.ToString( ("##,###,###") );
    }

    you are asking the CLR to call Dispose() on what ever objects declared or specified... in this case, your StreamWriter. Sometimes this can be a problem as you are cleaning up your object and then trying to use it again later.

    My suggestion would be either to axe the using statement or axe the call to Close() on objects you have specified inside of using.



  • Closed TextWriter