0

I am writing tracing class to find the execution time of modules/methods. I have a class like this

public class Trace
    {
        static Dictionary<string, Stopwatch> watches = null;

        static Trace()
        {
            Dictionary<string, Stopwatch> watches = new Dictionary<string, Stopwatch>();
        }

        public static void Start(string key, string losgMessage)
        {
            try
            {
                if (!watches.Keys.Contains(key))
                {
                    Stopwatch watch = new Stopwatch();
                    watch.Start();
                    watches.Add(key, watch);
                }
            }
            catch
            {
            }
        }

        public static void Stop(string key, Object logMessage, string sessionId)
        {
            try
            {

                if (!watches.Keys.Contains(key))
                {
                    Stopwatch watch = watches[key];
                    watch.Stop();
                    //log goes here
                }
            }
            catch
            {
            }
        }
    }

since wcf is multithreaded environment and the 'watches' static variable scope is application level, If some one(new rqst from the differnt client) tries to execute the same method with same key i will not consider it and trace it. So what would be the best option in this case. Any suggestion would be helpful.

edit : I am current appending sessionId with key. Cant i resolve this issue without session id

Al.
  • 855
  • 1
  • 11
  • 24

1 Answers1

1

Can't I resolve this issue without session Id

From the information provided, I would say no. If you have concurrent requests executing the same function call then you are going to get duplicate entries. The only way to avoid this is to ensure all keys are unique. I actually think using the session ID is required anyway, otherwise how can you map the function to the request?

Also, Dictionary isn't thread-safe (at least for writes), I would recommend using a ConcurrentDictionary.

James
  • 80,725
  • 18
  • 167
  • 237
  • if i use ConcurrentDictionary, dont i need to use lock before add/retreive/remove in ordinary dictionary? – Al. Sep 17 '12 at 12:41
  • "*don't I need to use lock before add/retrieve/remove*" - no, `ConcurrentDictionary` is thread-safe therefore can be accessed directly from multiple threads, all the locking is handled internally. – James Sep 17 '12 at 12:49
  • 1
    http://stackoverflow.com/questions/1949131/net-dictionary-locking-vs-concurrentdictionary -> Mark Byers claims it still needs lock. isnt it so – Al. Sep 17 '12 at 12:52
  • The point Mark Byers is making about race conditions e.g. you call `Contains` on the collection to check for a duplicate key, you then attempt to add that key if it doesn't exist. However, a concurrent thread could have added the same key inbetween calls. In your scenario, you don't have any reason to do this as all your keys will be unique. Also, `ConcurrentDictionary` has methods to avoid that sort of issue - [GetOrAdd](http://msdn.microsoft.com/en-us/library/ee378674.aspx) – James Sep 17 '12 at 13:00
  • thanks a lot.let me remove my lock and use ConcurrentDictionary – Al. Sep 17 '12 at 13:04
  • Just to clarify, the only thing you need to worry about is concurrent access to the collection, which `ConcurrentDictionary` should handle for you. Hope that helps. – James Sep 17 '12 at 13:07