views:

209

answers:

4

I'm using XML Writer to create a log of some important events in my application.

Currently it all works fine assuming that the application is correctly closed, but if it isnt, the file isnt closed and the log is basically lost.

Let's assume the writing of a simple element, something like this:

 writer.WriteStartElement(eventName);
 writer.WriteAttributeString("t", DateTime.Now.ToString());
 writer.WriteString(eventBody);
 writer.WriteEndElement();

Is there any way to close the file at this point and append the remaining elements to it later and only then closing the root element and xml writer?

+1  A: 

You can call the method writer.Flush() after your block of instructions. This should write the log and you won't lose any element.

Maurizio Reginelli
What about the end tag?
John Saunders
You can add another writer.Flush() after it and then close the writer.
Maurizio Reginelli
@Maurizio: I meant, what if the application fails after the flush but before the end tag can be written?
John Saunders
Just added the flush method and it does what i wanted, basically it shows up the last event before i forcefully exited the app. The outcome is an incomplete xml file, since the root element tag isnt closed but that is what i intended since the incomplete xml proves that something went wrong.Thnx
brokencoding
+1  A: 

The XmlWriter class implements the IDisposable interface. That means you must ensure that the Dispose method is called on your instance.

In addition, you should see the example at XmLWriterSettings.ConformanceLevel. It shows how to create an XmlWriter which is ok with writing a fragment. You can write a document with one log entry per element:

<SomeEvent t="20100228T134000Z">text</SomeEvent>
<SomeOtherEvent t="20100228T134100Z">text</SomeOtherEvent>

Just be sure to flush the writer after each.

John Saunders
A: 

Put your XmlWriter in a using statement;

    using (XmlWriter writer = XmlWriter.Create(stream))
    {
        writer.WriteStartElement("logentry");
        writer.WriteAttributeString("t", DateTime.Now.ToString());
        writer.WriteString("Something to log.");
        writer.WriteEndElement();
    }

You'll probably have to do some XmlDocumentFragment tricks also.

Mark Milbourne
Of course, the stream will have to append to the file. It may become expensive to open the file in append mode every time you have a log entry to write.
John Saunders
+1  A: 

See the first topic on this page, basically shows how to keep an XML log file without worrying about keeping the file open, and without worrying about what to do with the closing tag too. Hope you find it useful.

http://msdn.microsoft.com/en-us/library/aa302289.aspx

Binary Worrier
Be cautious about copy and paste of this code. It's six years old (you should not use `XmlTextWriter`, for instance), and is lacking `using` blocks around `IDisposable` resources.
John Saunders
The important part of the link is Xml inclusion, that's the trick the asked needs.
Binary Worrier