1

I am considering creating an asynchronous logging component having a dedicated thread that will read new items from queue and write to database, file, etc. If I create a thread as a background one - it will be terminated as soon as the process ends thus all items in queue will be lost. If I create it is a foreground one - I will have to figure out when to stop it as it will prevent the application from closing. Is there any way not to make developers remember to 'stop' logging functionality before application exits?

  • 8
    Don't create a dedicated thread to manage this in the first place...it'll be spending most of its time doing nothing. That's pretty wasteful for a logging framework. For that matter, avoid writing your own logging framework in the first place; it's a complex issue that already has many solutions available to you. – Servy Dec 20 '13 at 19:38
  • This other question might answer your question: [How do I create an asyncronous wrapper for log4net?](http://stackoverflow.com/q/7044497/1796930) – Alexander Dec 20 '13 at 19:38

2 Answers2

0

I believe you can:

  • Subscribe to the AppDomain.ProcessExit event;
  • Use a Volatile sentinel variable as a shutdown flag;
  • Set the flag when the ProcessExit event fires up;
  • Monitor the state of the flag inside your thread, and gracefully shut down accordingly.

This way you may keep a foreground thread aware of impending doom.

OnoSendai
  • 3,960
  • 2
  • 22
  • 46
  • 1
    It sounds like the OP has no way to gracefully shut down. It doesn't sound like his queue is persistent. – John Saunders Dec 20 '13 at 20:25
  • That seems to be the case, @JohnSaunders, I agree - but it also seems that he have some control over the way the dedicated thread is created. The answer may address his concern about preventing the application from closing. – OnoSendai Dec 20 '13 at 20:34
0

First of all I have to agree with the comments above. I would just use something like NLog rather than trying to roll my own. While it may seem like there is a lot to learn at first, it is still better than writing and debugging your own.

If you really want to travel this road, my recommendation would be to use a 'using' statement and IDisposable to control the asynchronous behavior. Just start a normal thread in the ctor and signal & Join the thread on Dispose().

Example usage:

void Main()
{
    using (new Logging())
    {
        ...
    }
}

Example class (untested):

class Logging :IDisposable
{
    ManualResetEvent _stop = new ManualResetEvent(false);
    Thread _worker = null;

    public Logging()
    {
        _worker = new Thread(AsyncThread);
        _worker.Start();
    }

    public void Dispose()
    {
        _stop.Set();
        _worker.Join();
    }

    public void AsyncThread()
    {
        ... 
    }
}    

In your logging routine, you will want to test if the thread is running and then decide between queuing the log write or directly appending to the log output. This way log messages before and after the async thread will continue to work correctly.

csharptest.net
  • 62,602
  • 11
  • 71
  • 89