A Better ExceptionXmlPublisher for the Exception Management Application Block.

This snippet incorporates part of a post from microsoft.public.dotnet.framework. It shows how to allow multiple threads to write to the same file at once, using a mutex to provide concurrency. This example is integrated with the Exception Management Block to provide a means of logging errors in multi-user applications to XML files.

using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.Specialized;
using Microsoft.ApplicationBlocks.ExceptionManagement;
using System.Threading;
using System.Diagnostics;

namespace DistributedArchitects.Exceptions
{
/// <SUMMARY>
/// Logs the XML data to the specified file.
/// </SUMMARY>
public class ExceptionXmlPublisher : IExceptionXmlPublisher
{
/// <SUMMARY>
/// Called by ExceptionManager through IExceptionXmlPublisher interface.
/// </SUMMARY>
/// <PARAM name="ExceptionInfo"> The XML DOM object containing the exception information</PARAM>
/// <PARAM name="ConfigSettings"> Configuration settings from the *.config file for this publisher. Requires the
/// fileName configuration attribute within the *.config file entry.</PARAM>
void IExceptionXmlPublisher.Publish(XmlDocument ExceptionInfo, NameValueCollection ConfigSettings)
{
OnPublish(ExceptionInfo,ConfigSettings);
}
/// <SUMMARY>
/// Overrideable implementation of IExceptionXmlPublisher.Publish interface method. Writes the
/// exception to file, using a mutex to allow for concurrent write operations to be
/// synchronized.
/// </SUMMARY>
/// <PARAM name="ExceptionInfo"> The XML DOM object containing the exception information</PARAM>
/// <PARAM name="ConfigSettings"> Configuration settings from the *.config file for this publisher. Requires the
/// fileName configuration attribute within the *.config file entry.</PARAM>
protected virtual void OnPublish(XmlDocument exceptionInfo, NameValueCollection configSettings)
{
string fileName;
if (configSettings != null)
{
fileName = configSettings["fileName"];
}
else
{
fileName = @"C:\ErrorLog.xml";
}

Mutex mutex = new Mutex(false, "mymutex.blah.blah");
if (!mutex.WaitOne())
{
//TODO: What to do with the error if this block fails?
// For now, log to event log and swallow the error.
EventLog log = new EventLog("ErrorLog");;
try
{
if(!EventLog.SourceExists("debugging"))
{
EventLog.CreateEventSource("debugging", "ErrorLog");
}
log.Source = "debugging";
log.WriteEntry("Unable to create mutex in ExceptionXmlPublisher.",System.Diagnostics.EventLogEntryType.Error);
return;
}
finally
{
log.Dispose();
}
}

try
{
using (FileStream fs = File.Open(fileName, FileMode.Append ,FileAccess.Write,FileShare.Write ) )
{
StreamWriter writer = new StreamWriter(fs);
writer.Write(exceptionInfo.OuterXml);
writer.Flush();
}
}
finally
{
mutex.ReleaseMutex();
}
}
}
}

<Kirk />