public void Append(LogItem logItem) { _log.Add(logItem); }
static void Run(object param) { TaskParam taskParam; if ((taskParam = param as TaskParam) == null) { return; } Console.WriteLine("{0}\t{1} started...", DateTime.Now.ToString(LogItem.FormatString), taskParam.i); var rnd = new Random(Thread.CurrentThread.ManagedThreadId); for (var i = 0; i < 10; ++i) { int nodeNo, millisecondsTimeout = taskParam.mSec * rnd.Next(10); Console.WriteLine("{0}\t{1} i={2} (will sleep {3}ms)", DateTime.Now.ToString(LogItem.FormatString), taskParam.i, i, millisecondsTimeout); if ((nodeNo = rnd.Next(taskParam.nodesMax)) < taskParam.nodesMax) { var _lock = new ReaderWriterLockSlim(); DateTime dateTimeBeforeLock = DateTime.Now, dateTimeAfterLock; bool nodeNeedAdd; LogItem logItemBeforeEnterReadLock, logItemAfterEnterReadLock, logItemAfterExitReadLock, logItemBeforeEnterWriteLock = null, logItemAfterEnterWriteLock = null, logItemNodeHasBeenAdded = null, logItemAfterExitWriteLock = null, logItemBeforeLock, logItemAfterLock; logItemBeforeEnterReadLock = new LogItem(taskParam.i, i, $"b4 EnterReadLock() for check node {nodeNo}", nodeNo, dateTimeBeforeLock); Console.WriteLine("{0}\t{1} i={2} b4 EnterReadLock() for check node {3}", dateTimeBeforeLock.ToString(LogItem.FormatString), taskParam.i, i, nodeNo); _lock.EnterReadLock(); try { dateTimeAfterLock = DateTime.Now; logItemAfterEnterReadLock = new LogItem(taskParam.i, i, $"after EnterReadLock() for check node {nodeNo} successfully", nodeNo, dateTimeBeforeLock, dateTimeAfterLock); Console.WriteLine("{0}\t{1} i={2} after EnterReadLock() for check node {3} successfully (b4 {4} wait {5}ms)", dateTimeAfterLock.ToString(LogItem.FormatString), taskParam.i, i, nodeNo, dateTimeBeforeLock.ToString(LogItem.FormatString), (dateTimeAfterLock - dateTimeBeforeLock).TotalMilliseconds); nodeNeedAdd = !taskParam.victim.ContainsKey(nodeNo); } finally { _lock.ExitReadLock(); dateTimeAfterLock = DateTime.Now; logItemAfterExitReadLock = new LogItem(taskParam.i, i, $"after ExitReadLock() for check node {nodeNo} successfully", nodeNo, dateTimeBeforeLock, dateTimeAfterLock); Console.WriteLine("{0}\t{1} i={2} after ExitReadLock() for check node {3} successfully (b4 {4} wait {5}ms)", DateTime.Now.ToString(LogItem.FormatString), taskParam.i, i, nodeNo, dateTimeBeforeLock.ToString(LogItem.FormatString), (dateTimeAfterLock - dateTimeBeforeLock).TotalMilliseconds); } if (nodeNeedAdd) { dateTimeBeforeLock = DateTime.Now; logItemBeforeEnterWriteLock = new LogItem(taskParam.i, i, $"b4 EnterWriteLock() for check node {nodeNo}", nodeNo, dateTimeBeforeLock); Console.WriteLine("{0}\t{1} i={2} b4 EnterWriteLock() for check node {3}", dateTimeBeforeLock.ToString(LogItem.FormatString), taskParam.i, i, nodeNo); _lock.EnterWriteLock(); try { dateTimeAfterLock = DateTime.Now; logItemAfterEnterWriteLock = new LogItem(taskParam.i, i, $"after EnterWriteLock() for check node {nodeNo} successfully", nodeNo, dateTimeBeforeLock, dateTimeAfterLock); Console.WriteLine("{0}\t{1} i={2} after EnterWriteLock() for check node {3} successfully (b4 {4} wait {5}ms)", dateTimeAfterLock.ToString(LogItem.FormatString), taskParam.i, i, nodeNo, dateTimeBeforeLock.ToString(LogItem.FormatString), (dateTimeAfterLock - dateTimeBeforeLock).TotalMilliseconds); taskParam.victim.Add(nodeNo, new Log()); logItemNodeHasBeenAdded = new LogItem(taskParam.i, i, $"node {nodeNo} has been added", nodeNo, DateTime.Now); Console.WriteLine("{0}\t{1} i={2} node {3} has been added", DateTime.Now.ToString(LogItem.FormatString), taskParam.i, i, nodeNo); } finally { _lock.ExitWriteLock(); dateTimeAfterLock = DateTime.Now; logItemAfterExitWriteLock = new LogItem(taskParam.i, i, $"after ExitWriteLock() for check node {nodeNo} successfully", nodeNo, dateTimeBeforeLock, dateTimeAfterLock); Console.WriteLine("{0}\t{1} i={2} after ExitWriteLock() for check node {3} successfully (b4 {4} wait {5}ms)", DateTime.Now.ToString(LogItem.FormatString), taskParam.i, i, nodeNo, dateTimeBeforeLock.ToString(LogItem.FormatString), (dateTimeAfterLock - dateTimeBeforeLock).TotalMilliseconds); } } dateTimeBeforeLock = DateTime.Now; logItemBeforeLock = new LogItem(taskParam.i, i, $"trying to lock node {nodeNo}", nodeNo, dateTimeBeforeLock); Console.WriteLine("{0}\t{1} i={2} trying to lock node {3}", dateTimeBeforeLock.ToString(LogItem.FormatString), taskParam.i, i, nodeNo); lock (taskParam.victim[nodeNo]) { dateTimeAfterLock = DateTime.Now; var millisecondsTimeoutForLock = taskParam.mSec * rnd.Next(10); logItemAfterLock = new LogItem(taskParam.i, i, $"has locked node {nodeNo} successfully (will sleep {millisecondsTimeoutForLock}ms)", nodeNo, dateTimeBeforeLock, dateTimeAfterLock); taskParam.victim[nodeNo].Append(logItemBeforeEnterReadLock); taskParam.victim[nodeNo].Append(logItemAfterEnterReadLock); taskParam.victim[nodeNo].Append(logItemAfterExitReadLock); if (logItemBeforeEnterWriteLock != null) { taskParam.victim[nodeNo].Append(logItemBeforeEnterWriteLock); } if (logItemAfterEnterWriteLock != null) { taskParam.victim[nodeNo].Append(logItemAfterEnterWriteLock); } if (logItemNodeHasBeenAdded != null) { taskParam.victim[nodeNo].Append(logItemNodeHasBeenAdded); } if (logItemAfterExitWriteLock != null) { taskParam.victim[nodeNo].Append(logItemAfterExitWriteLock); } taskParam.victim[nodeNo].Append(logItemBeforeLock); taskParam.victim[nodeNo].Append(logItemAfterLock); Console.WriteLine("{0}\t{1} i={2} has locked node {3} successfully (will sleep {6}ms) (b4lock {4} wait {5}ms)", dateTimeAfterLock.ToString(LogItem.FormatString), taskParam.i, i, nodeNo, dateTimeBeforeLock.ToString(LogItem.FormatString), (dateTimeAfterLock - dateTimeBeforeLock).TotalMilliseconds, millisecondsTimeoutForLock); Thread.Sleep(millisecondsTimeoutForLock); var tmpDateTime = DateTime.Now; taskParam.victim[nodeNo].Append(new LogItem(taskParam.i, i, $"has released node {nodeNo} successfully", nodeNo, dateTimeAfterLock, tmpDateTime)); Console.WriteLine("{0}\t{1} i={2} has released node {3} successfully (b4lock {4} wait {5}ms)", tmpDateTime.ToString(LogItem.FormatString), taskParam.i, i, nodeNo, dateTimeAfterLock.ToString(LogItem.FormatString), (tmpDateTime - dateTimeAfterLock).TotalMilliseconds); } } Thread.Sleep(millisecondsTimeout); } Console.WriteLine("{0}\t{1} finished", DateTime.Now.ToString(LogItem.FormatString), taskParam.i); }