Hey Ron,

 

I actually implemented something similar in a product we're distributing.
There I used plain delegates (lambda expressions) in favour of not having a
dependency to the TPL library, but that's not the big deal anyway. It works
astonishingly well, but I had to add a small safety condition:

 

Since the creation of asynchronous logging events is extremely fast and
blocks the application almost for no-time, any application could possibly
overflow the logging facility with so much events that it can't handle them
anymore. The result is that the queues grow and grow until the application
goes out of memory.

 

The solution I made is simple, but effective. Before the logging event is
processed asynchronously, I check the queue size and decide there if I
should block the calling application for a small portion of time per logging
event. I.e. something similar to this:

 

                        public void QueueUserWorkItem(T item)

                        {

                                   bool blockInvoker = false;

                                   int blockTime = 0;

 

                                   lock (itemsLock)

                                   {

                                               // queue the item

                                               items.Enqueue(item);

 

                                               if (items.Count > 1000)

                                               {

                                                           blockInvoker =
true;

                                                           if (items.Count >
1000000)

 
blockTime = 10;

                                                           else if
(items.Count > 500000)

 
blockTime = 5;

                                                           else if
(items.Count > 250000)

 
blockTime = 3;

                                                           else if
(items.Count > 100000)

 
blockTime = 2;

                                                           else if
(items.Count > 50000)

 
blockTime = 1; // actually block the application

                                                           else if
(items.Count > 10000)

 
blockTime = 0; // give another thread the chance to get the cpu

                                               }

                                   }

 

                                   // out of any lock (such that we dont
lock ourselves) block the invoker

                                   if (blockInvoker)

                                   {

                                               Thread.Sleep(blockTime);

                                   }

                        }

 

This gradually slows the calling application and works pretty fine if one
does stupid things like:

 

while (true) {

  logger.Info("yehaw");

}

 

JMTC,

Dominik

 

  _____  

From: Ron Grabowski [mailto:rongrabow...@yahoo.com] 
Sent: Thursday, September 29, 2011 5:59 AM
To: log4net-dev
Subject: TPL DataFlows

 

Has anyone played around with TPL DataFlows yet? It looks like it could be
next step beyond using a concurrent queue for async message processing. Once
a log event has had the appropriate thread specific properties evaluated it
could be posted to a BroadcastBlock which would asynchronously post the
message to appenders:

 

http://weblogs.asp.net/mjarguello/archive/2011/03/15/asynchrony-in-c-5-dataf
low-async-logger-sample.aspx

 

 

 

 

Reply via email to