Search code examples
c#disposeflushhtmltextwriter

HtmlTextWriter doesn't flush upon disposal?


I need to write some text with style (like color, fonts) so I decided to use html. I found that HtmlTextWriter is a class used for writing html file. However, I found that I must manually close or flush it otherwise nothing is written to the file. Why is it? (using statement should dispose it when the block is finished)

        using (HtmlTextWriter htmlWriter = new HtmlTextWriter(new StreamWriter(
            Path.Combine(EmotionWordCounts.FileLocations.InputDirectory.FullName, fileName),
            false, Encoding.UTF8)))
        {
            try
            {

                htmlWriter.WriteFullBeginTag("html");
                htmlWriter.WriteLine();
                htmlWriter.Indent++;

                htmlWriter.WriteFullBeginTag("body");
                htmlWriter.WriteLine();
                htmlWriter.Indent++;

                // write something using WriteFullBeginTag and WriteEndTag
                // ...

            } //try
            finally
            {
                htmlWriter.Indent--;
                htmlWriter.WriteEndTag("body");
                htmlWriter.WriteLine();

                htmlWriter.Indent--;
                htmlWriter.WriteEndTag("html");
                htmlWriter.Close(); // without this, the writer doesn't flush
            }
        } //using htmlwriter

Thanks in advance.


Solution

  • This is a bug in HtmlTextWriter. You should make a self-contained test case and report it using Microsoft Connect. It seems that Close and Dispose behave differently, which isn't documented and is extremely unusual. I also can't find any documentation on MSDN stating whether the HtmlTextWriter takes ownership of the underlying textwriter or not; i.e. will it dispose the underlying textwriter or must you?

    Edit 2: The MSDN page on HtmlTextWriter states that it inherits (as opposed to overrides) the virtual Dispose(bool) method. This means the current implementation clearly cannot clean up with a using block. As a workaround, try this:

    using(var writer = ...make TextWriter...) 
    using(var htmlWriter = new HtmlTextWriter(writer)) {
    
        //use htmlWriter here...
    
    } //this should flush the underlying writer AND the HtmlTextWriter
    
    // although there's currently no need to dispose HtmlTextWriter since
    // that doesn't do anything; it's possibly better to do so anyhow in 
    // case the implementation gets fixed
    

    Incidentally, new StreamWriter(XYZ, false, Encoding.UTF8) is equivalent to new StreamWriter(XYZ). StreamWriter creates rather than appends by default, and it uses UTF8 without BOM by default as well.

    Good luck - and don't forget to report the bug!