[dba-VB] c# lock()

Shamil Salakhetdinov shamil at smsconsulting.spb.ru
Thu Mar 10 15:36:58 CST 2011


Hi John --

Here is sample code I promised to post.

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Log
    {
        public static bool On { get; set; }
        public static void WriteLine(string message)
        {
            WriteLine(message, false);  
        }
        public static void WriteLine(string message, bool forceLogging)
        {
            if (Log.On || forceLogging) System.Console.WriteLine(message);
        }
    }

    class MyObject
    {
        static int _newId;
        public MyObject() 
        { 
            _id = System.Threading.Interlocked.Increment(ref _newId);    
            _timeStamp = DateTime.Now; 
        }
        int _id;
        public int ID { get { return _id; } set { _id = value; } }
        DateTime _timeStamp;
        public DateTime TimeStamp { get { return _timeStamp; } set {
_timeStamp = value; } }

     }

    class MyObjectsStore
    {
        private List<int> _keys = new List<int>(); 
        private Dictionary<int, MyObject> _myObjects = new Dictionary<int,
MyObject>();
        public MyObject this[int key]
        {
            get
            {
                 MyObject myObject = null;
                lock (_myObjectsLocker)
                {
                    _myObjects.TryGetValue(key, out myObject);   
                }
                return myObject;
            }
        }

        public int Count
        {
            get
            {
                lock (_myObjectsLocker)
                {
                    return _myObjects.Count;
                }
            }
        }

        private static object _myObjectsLocker = new object();
        public void Add(MyObject myObject)
        {
            lock (_myObjectsLocker)
            {
                _myObjects.Add(myObject.ID, myObject);
                _keys.Add(myObject.ID);    
            }
        }
        public MyObject Remove(int id)
        {
            MyObject myobject = null;
            lock (_myObjectsLocker)
            {
                myobject = _myObjects[id]; 
                _myObjects.Remove(id);
            }
            return myobject; 
        }

        static Random _rnd = new Random(); 
        public MyObject RemoveRandomObject()
        {
            MyObject myobject = null;
            int index = -1;
            int key = -1;
            try
            {
                lock (_myObjectsLocker)
                {
                    index = _rnd.Next(_keys.Count - 1);
                    key = _keys[index];
                    myobject = Remove(key); 
                    _keys.Remove(key); 
                }
            }
            catch (Exception ex)
            {
                Log.WriteLine(string.Format("[{0}]: RemoveRandomObject: {1},
index = {2}, key = {3}", 
                    System.Threading.Thread.CurrentThread.ManagedThreadId,
                    ex.Message, index , key));  
            }
            return myobject; 
        }

    }

    class Program
    {
        public const int OBJECTS_PER_THREAD_COUNT = 7;
        public const int REMOVAL_MAX_RETRIES_COUNT = 5;
        public static void AddObjectsTest()
        {
            for (int i = 1; i <= OBJECTS_PER_THREAD_COUNT; i++)
            {
                MyObject myObject = new MyObject();
                _store.Add(myObject);
                Log.WriteLine(string.Format("[{0}]: Object Added - ID = {1},
TS = {2}",
                     System.Threading.Thread.CurrentThread.ManagedThreadId,
myObject.ID, myObject.TimeStamp.Ticks));
                System.Threading.Thread.Sleep(2);
                System.Threading.Interlocked.Increment(ref
_createdObjectsCount); 
            }

            System.Threading.Interlocked.Decrement(ref _threadsCount);
        }
        public static void RemoveObjectsTest()
        {

            for (int i = 1; i <= OBJECTS_PER_THREAD_COUNT; i++)
            {
                int retryCount = REMOVAL_MAX_RETRIES_COUNT;
            retry:
                MyObject myObject = _store.RemoveRandomObject();
                if (myObject != null)
                {
                    Log.WriteLine(string.Format("[{0}]: Object Removed - ID
= {1}, TS = {2}",
 
System.Threading.Thread.CurrentThread.ManagedThreadId, myObject.ID,
myObject.TimeStamp.Ticks));
                    System.Threading.Thread.Sleep(2);
                }

                System.Threading.Thread.Sleep(2);

                if (myObject == null && --retryCount >= 0)
                {
                    Log.WriteLine(string.Format("[{0}]: Object Removal
failed, retry attempt# {1}",
 
System.Threading.Thread.CurrentThread.ManagedThreadId,
REMOVAL_MAX_RETRIES_COUNT-retryCount));
                    System.Threading.Interlocked.Increment(ref
_totalRetriesCount);
                    goto retry;
                }
                else if (myObject == null)
                {
                    Log.WriteLine(string.Format("[{0}]: Object Removal
failed",
 
System.Threading.Thread.CurrentThread.ManagedThreadId));
                    System.Threading.Interlocked.Increment(ref
_failedObjectRemovalsCount);   
                }
                else System.Threading.Interlocked.Increment(ref
_removedObjectsCount); 
            }

            System.Threading.Interlocked.Decrement(ref _threadsCount);
        }

        static int _createdObjectsCount;
        static int _removedObjectsCount;
        static int _totalRetriesCount;
        static int _failedObjectRemovalsCount;
        static int _threadsCount;
        static MyObjectsStore _store;

        const int THREADS_COUNT = 20; //000;

        static void Main(string[] args)
        {
            Log.On = true;  
            Log.WriteLine(string.Format("{0}: Test Started.",
DateTime.Now));  
            try
            {
                Log.On = false;
                _store = new MyObjectsStore();
                for (int i = 1; i <= THREADS_COUNT; i++)
                {
                    if (i % 2 == 1)
                        new System.Threading.Thread(
                            new
System.Threading.ThreadStart(AddObjectsTest))
                            .Start();
                    else
                        new System.Threading.Thread(
                            new
System.Threading.ThreadStart(RemoveObjectsTest))
                            .Start();

                    _threadsCount++;
                }

                while (_threadsCount > 0)
System.Threading.Thread.Sleep(100);

                System.Threading.Thread.Sleep(100);

                Log.On = true;
                Log.WriteLine(string.Format("Total Threads Count = {0}",
THREADS_COUNT));
                Log.WriteLine(string.Format("Store has {0} objects, Created
= {1}, Removed = {2}",
                      _store.Count, _createdObjectsCount,
_removedObjectsCount));
                Log.WriteLine(string.Format("RemovalRetriesCount = {0},
FailedRemovalsCount = {1}",
                      _totalRetriesCount, _failedObjectRemovalsCount));  

            }
            catch (Exception ex)
            {
                Log.On = true;  
                Log.WriteLine(string.Format("Program.Main: " + ex.Message));

            }
            finally
            {
                Log.On = true;  
            }
            Log.WriteLine(string.Format("{0}: Test Finished.",
DateTime.Now));
        }
    }
}


Thank you.

--
Shamil
 
-----Original Message-----
From: dba-vb-bounces at databaseadvisors.com
[mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby
Sent: 10 ????? 2011 ?. 16:13
To: VBA
Subject: [dba-VB] c# lock()

<<< snip >>>




More information about the dba-VB mailing list