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