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 >>>