Wait for logwriters

Topics: Logging Application Block
Oct 13, 2014 at 1:43 PM

I am using the logging block in an async manner. However if the application crashes or is exited the "log queue" is lost. Is there a way to "flush" or "wait for all loggers" thing?

Also changing the log thread to foreground would probably help a lot.

Oct 14, 2014 at 1:35 AM
If you are using in-memory queuing then there is always a risk of losing queued items in the event of a crash. So you should weigh the pros and cons of the approach as well as tuning the buffer size to avoid queuing more items than necessary or that you are willing to lose.

For a normal shutdown before exiting the program the LogWriter should be disposed which will flush the buffer(s):

// Program Init
var logFactory = new LogWriterFactory();
var writer = logFactory.Create();

// Normal program execution
writer.Write("Test1", "General");
writer.Write("Test2", "General");
writer.Write("Test3", "General");

// Program exit
if (writer != null)

If you are using the static facade instead of a LogWriter instance then you can use the Logger.Writer.Dispose(); method.

Randy Levy
Enterprise Library support engineer
Support How-to
Oct 14, 2014 at 9:22 AM
Edited Oct 14, 2014 at 1:34 PM
I disagree.
In case of a crash, you are usually able to detect it, delay it and exit as gracefull as possible. Part of such an approach is using the AppDomain.UnhandledException event.

Further, if your application just exits you do lose the queue, just because the log wrting thread is backgrounded. Introducing reliable quing won't solve this, since adding to the queue will be async and may also lose items. Regardless the overkill of introducing reliable queing (considering the infrastructure and management) to very simple applications.

However .Dispose solves some of the issues.

Now I just need to figure a way to delay a process exit (gracefull) or change the queue Task threads to foreground. AppDomain.ProcessExit has a windows based timeout of two seconds - Any Suggestions?
Oct 14, 2014 at 5:01 PM
I don't disagree with you -- I was just focusing on the worst case unrecoverable scenario while you are focusing on a recoverable scenario.

When Dispose is called all buffered LogEntries should be processed and then Dispose will return. From AsynchronousTraceListenerWrapper:

When disposed, the wrapper will attempt to complete all buffered tracing requests before completing the dispose request. To change this behavior specify a value for the disposeTimeout constructor parameter other than nulla null reference (Nothing in Visual Basic) or InfiniteTimeSpan.

A general rule is: when using asynchronous trace listeners perform a Dispose before exiting (either normally or due to an exception).

If you specify a DisposeTimeout then Dispose will wait the specified interval before cancelling the dequeuing operation.

Randy Levy
Enterprise Library support engineer
Support How-to