Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2008

Tip: Looking for answers? Try searching our database.

multi-threaded request counter

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Peter - 25 Mar 2008 10:10 GMT
Hi

In a multi-threaded application I need to keep track of request-counts
for various "users". That is, when a user makes a request to my
application I need to increment a counter to track the number of times
the user has made a request.

But a "user" is more than a single entity, and the same user can be
calling my application simultaneously.

How do I keep track of a user's requests? If I use a simple Hashtable
(with the users' unique ids as keys) to contain the counts, when I get
the count from the Hashtable to update it, the same user could be
making another request simultaneously, and the counts will not be
accurate.

I don't want to lock the entire Hashtable, because I am worried that
will badly affect performance - as if several different users are
calling simultaneously then they will have to wait for each other.

Any ideas to how I can implement a counter for user requests?

Thanks,
Peter
Jon Skeet [C# MVP] - 25 Mar 2008 11:54 GMT
> In a multi-threaded application I need to keep track of request-counts
> for various "users". That is, when a user makes a request to my
[quoted text clipped - 15 lines]
>
> Any ideas to how I can implement a counter for user requests?

Rather than *worry* about locking the entire hashtable badly affecting
performance, *measure* it. You only need to lock for the amount of time
it takes to fetch the entry and update it.

Unless you are processing hundreds of thousands of requests per second,
I doubt it will actually affect performance that badly.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Marc Gravell - 25 Mar 2008 12:03 GMT
> I don't want to lock the entire Hashtable, because I am worried that
> will badly affect performance - as if several different users are
> calling simultaneously then they will have to wait for each other.

They'd only need to be synchronized while logging that a request happened -
not for the actual duration of the request. In most cases I would imagine
that this won't create a bottleneck (compared to everything else going on),
so until profiling *shows* that you have a problem, I'd use synchronized
access to a dictionary<something, int> where something relates to your user
id.

Something like (off the cuff code):

static class UserCounters
{
   private static readonly Dictionary<string, int> counter =
       new
Dictionary<string,int>(StringComparer.InvariantCultureIgnoreCase);
   public static void LogAccess(string cn)
   {
       lock (counter)
       {
           int value;
           if (counter.TryGetValue(cn, out value))
           {
               counter[cn] = value + 1;
           }
           else
           {
               counter.Add(cn, 1);
           }
       }
   }
   public static KeyValuePair<string, int>[] Dump(bool reset)
   {
       lock (counter)
       {
           KeyValuePair<string, int>[] data = new KeyValuePair<string,
int>[counter.Count];
           int index = 0;
           foreach (KeyValuePair<string, int> pair in counter)
           {
               data[index++] = pair;
           }
           if (reset)
           {
               counter.Clear();
           }
           return data;
       }
   }
}
Peter - 25 Mar 2008 13:42 GMT
> They'd only need to be synchronized while logging that a request
> happened - not for the actual duration of the request.

>    public static KeyValuePair<string, int>[] Dump(bool reset)
>    {
[quoted text clipped - 13 lines]
>        }
>    }

OK, thanks for the answer (and to Jon), and for the code - which is
similar to what I had.

It touches on another problem though, because in my system I also need
to store data besides the simple int count. So I made a simple data
object to hold all the user-request-count data I needed, but soon
discovered that with a method like your Dump, the client receives a
data object which it could then alter - upsetting the values stored in
the hashtable.

Is the way to avoid this to return data-objects which only have getters
(no setters) - and/or to actually return copies of the real
data-objects from the hashtable?

/Peter
Lasse Vågsæther Karlsen - 25 Mar 2008 14:33 GMT
>> They'd only need to be synchronized while logging that a request
>> happened - not for the actual duration of the request.
[quoted text clipped - 32 lines]
>
> /Peter

What exactly is in this "counter" of yours?

If you want precise and helpful answers, you need to give precise and
helpful information as well. A simple counter can be done like the other
posts here have indicated, but something more advanced might need
something more advanced.

Do you need realtime up to date statistics about something? Or do you
just need to know at some later date? If so, perhaps a simple log could
do that wouldn't necessarily need to interfere with previous data at
all, and then some sort of program that tallied up the results when
needed...

Signature

Lasse Vågsæther Karlsen
mailto:lasse@vkarlsen.no
http://presentationmode.blogspot.com/
PGP KeyID: 0xBCDEA2E3


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.