I'm developing a Smart Array (it's a request I cannot use a List of int that I know it's easier because I made both codes). I have done this class and below is the example of how I use it. The error is often in this line (153 from class):
// Ensure that the lock is released.Monitor.Exit(array);
If I use a List nothing wrong happens just when I translate to an array. Thanks for your help.
SmartArray3.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SmartArray { class SmartArray3 { private int[] array; private int size = 0; private int count = 0; public SmartArray3() { Resize(1); } public SmartArray3(int size) { this.size = size; array = new int[this.size]; } public bool Resize(int size) { try { if (array == null) array = new int[size]; else Array.Resize(ref array, size); this.size++; return true; } catch { return false; } } private void add(int value) { try { if (array == null) { this.size = 1; Resize(this.size); array[0] = value; this.count++; } else { if (this.count == (this.size - 1)) { this.size *= 2; this.Resize(this.size); } if ((this.count - 1) < 0) array[0] = value; else array[this.count - 1] = value; this.count++; } } catch (Exception ex) { Console.Write(ex.ToString()); throw new System.IndexOutOfRangeException("Index out of Range."); } } // Lock the array and add an element. public void Add(int value) { // Request the lock, and block until it is obtained. Monitor.Enter(array); try { if (array == null) { this.size = 1; Resize(this.size); array[0] = value; this.count++; } else { if (this.count == (this.size - 1)) { this.size *= 2; this.Resize(this.size); } if ((this.count - 1) < 0) array[0] = value; else array[this.count - 1] = value; this.count++; } } finally { // Ensure that the lock is released. Monitor.Exit(array); } } // Try to add an element to the List: Add the element to the List // only if the lock is immediately available. public bool TryAdd(int value) { // Request the lock. if (Monitor.TryEnter(array)) { try { if (array == null) { this.size = 1; Resize(this.size); array[0] = value; this.count++; } else { if (this.count == (this.size - 1)) { this.size *= 2; this.Resize(this.size); } if ((this.count - 1) < 0) array[0] = value; else array[this.count - 1] = value; this.count++; } } finally { // Ensure that the lock is released. Monitor.Exit(array); } return true; } else { return false; } } public int Get(int index) { try { return array[index]; } catch (IndexOutOfRangeException ex) { throw new System.IndexOutOfRangeException("Index out of range"); } } } }
Code for called the Class:
private static int threadsRunning = 0; private SmartArray3 sa = new SmartArray3(); private List<double> times; private static string[] titles ={ "Add ", "Add failed ", "TryAdd succeeded ", "TryAdd failed "}; private static int[][] results = new int[3][]; //Event to Create Threads private void newTest() { for (int i = 0; i < 3; i++) { Thread t = new Thread(ThreadProc); t.Start(i); Interlocked.Increment(ref threadsRunning); } } private void ThreadProc(object state) { times = new List<double>(); DateTime finish = DateTime.Now.AddSeconds(10); Random rand = new Random(); int[] result = { 0, 0, 0, 0}; int threadNum = (int)state; while (DateTime.Now < finish) { Stopwatch sw = Stopwatch.StartNew(); int what = rand.Next(250); int how = rand.Next(25); if (how < 16) { try { sa.Add(what); result[(int)ThreadResultIndex.AddCt] += 1; times.Add(sw.Elapsed.TotalMilliseconds); } catch { result[(int)ThreadResultIndex.AddFailCt] += 1; } } else { if (sa.TryAdd(what)) { result[(int)ThreadResultIndex.TryAddSucceedCt] += 1; } else { result[(int)ThreadResultIndex.TryAddFailCt] += 1; } } sw.Stop(); } results[threadNum] = result; if (0 == Interlocked.Decrement(ref threadsRunning)) { StringBuilder sb = new StringBuilder( " Thread 1 Thread 2 Thread 3 Total\n"); for (int row = 0; row < 4; row++) { int total = 0; sb.Append(titles[row]); for (int col = 0; col < 3; col++) { sb.Append(String.Format("{0,4} ", results[col][row])); total += results[col][row]; } sb.AppendLine(String.Format("{0,4} ", total)); } Console.WriteLine(sb.ToString()); } } private enum ThreadResultIndex { AddCt, AddFailCt, TryAddSucceedCt, TryAddFailCt }