Hi Nick,
The advantage of writing a class that Inherits from TraceListener is that
you can write your own custom listener that is not provided as standard by
Microsoft, I did this to send my trace messages over a network using remoting.
One way to achieve asyncronosity is to have the main app thread write data
into the log queue, then a seperate thread sits and waits for the data and
pulls it out of the queue and performs processing. This consumer thread will
loop until it is told to stop, when there is no data it will just wait until
more data is added to the log. In the example below I used an AutoResetEvent
to make the thread wait until the Producer added more data to the queue:
using System;
using System.Threading;
using System.Collections;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
MessageManager mm = new MessageManager();
Random random = new Random();
int numberofMessages = 100;
int count = 0;
while (count++ < numberofMessages)
{
mm.AddMessage("hello: " + count.ToString());
Thread.Sleep((int)(random.NextDouble() * 300));
}
}
}
public class MessageManager
{
private AutoResetEvent _consumerWait;
private Queue _queue;
private Thread _consumer;
private bool _continueProcessing;
public MessageManager()
{
_queue = new Queue();
_consumerWait = new AutoResetEvent(false);
_continueProcessing = true;
_consumer = new Thread(new ThreadStart(ConsumeMessages));
_consumer.IsBackground = true;
_consumer.Start();
}
private void Stop()
{
_continueProcessing = false;
_consumerWait.Set();
}
private void ConsumeMessages()
{
//Loop until we no longer want to process messages
while (_continueProcessing)
{
//process all the current messages
while (_queue.Count > 0)
{
string message = (string)_queue.Dequeue();
Console.WriteLine(message);
}
//wait until there is data to process
_consumerWait.WaitOne();
}
}
public void AddMessage(string message)
{
//Add message to the queue
_queue.Enqueue(message);
//Signal there is more data
_consumerWait.Set();
}
}
Hope that helps
Mark R Dawson
http://www.markdawson.org
Nick Z. said:
This looks interesting. However, what would be the advantage of
implementing a TraceListener? XmlWriterTraceListener sounds like a great
idea, but its only supported in 2.0. For a class like this I'd rather
have it support all versions of the framework.
I am probably going to do the same. This sounds very efficient.
However, isn't the writing done in a separate thread anyway? So in a
sense aren't you implementing a thread that simply starts another thread
to write the log.
Just out of curiosity, when the thread that is writing the messages runs
out of messages to write, does it terminate or wait for new messages to
come in. If it waits how could that be implemented?