1. 程式人生 > >.NET並行計算和並發11:並發接口 IProducerConsumerCollection

.NET並行計算和並發11:並發接口 IProducerConsumerCollection

imp hit message rate expec demo rod new bject

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.Collections.Concurrent;
  5 using System.Linq;
  6 using System.Threading;
  7 using System.Threading.Tasks;
  8 
  9 
 10 // Sample implementation of IProducerConsumerCollection(T) 
 11 // -- in this case, a thread-safe stack.
12 public class SafeStack<T> : IProducerConsumerCollection<T> 13 { 14 // Used for enforcing thread-safety 15 private object m_lockObject = new object(); 16 17 // We‘ll use a regular old Stack for our core operations 18 private Stack<T> m_sequentialStack = null; 19
20 // 21 // Constructors 22 // 23 public SafeStack() 24 { 25 m_sequentialStack = new Stack<T>(); 26 } 27 28 public SafeStack(IEnumerable<T> collection) 29 { 30 m_sequentialStack = new Stack<T>(collection); 31 } 32 33 //
34 // Safe Push/Pop support 35 // 36 public void Push(T item) 37 { 38 lock (m_lockObject) m_sequentialStack.Push(item); 39 } 40 41 public bool TryPop(out T item) 42 { 43 bool rval = true; 44 lock (m_lockObject) 45 { 46 if (m_sequentialStack.Count == 0) { item = default(T); rval = false; } 47 else item = m_sequentialStack.Pop(); 48 } 49 return rval; 50 } 51 52 // 53 // IProducerConsumerCollection(T) support 54 // 55 public bool TryTake(out T item) 56 { 57 return TryPop(out item); 58 } 59 60 public bool TryAdd(T item) 61 { 62 Push(item); 63 return true; // Push doesn‘t fail 64 } 65 66 public T[] ToArray() 67 { 68 T[] rval = null; 69 lock (m_lockObject) rval = m_sequentialStack.ToArray(); 70 return rval; 71 } 72 73 public void CopyTo(T[] array, int index) 74 { 75 lock (m_lockObject) m_sequentialStack.CopyTo(array, index); 76 } 77 78 79 80 // 81 // Support for IEnumerable(T) 82 // 83 public IEnumerator<T> GetEnumerator() 84 { 85 // The performance here will be unfortunate for large stacks, 86 // but thread-safety is effectively implemented. 87 Stack<T> stackCopy = null; 88 lock (m_lockObject) stackCopy = new Stack<T>(m_sequentialStack); 89 return stackCopy.GetEnumerator(); 90 } 91 92 93 // 94 // Support for IEnumerable 95 // 96 IEnumerator IEnumerable.GetEnumerator() 97 { 98 return ((IEnumerable<T>)this).GetEnumerator(); 99 } 100 101 // 102 // Support for ICollection 103 // 104 public bool IsSynchronized 105 { 106 get { return true; } 107 } 108 109 public object SyncRoot 110 { 111 get { return m_lockObject; } 112 } 113 114 public int Count 115 { 116 get { return m_sequentialStack.Count; } 117 } 118 119 public void CopyTo(Array array, int index) 120 { 121 lock (m_lockObject) ((ICollection)m_sequentialStack).CopyTo(array, index); 122 } 123 } 124 125 public class Program 126 { 127 static void Main() 128 { 129 TestSafeStack(); 130 131 // Keep the console window open in debug mode. 132 Console.WriteLine("Press any key to exit."); 133 Console.ReadKey(); 134 } 135 136 // Test our implementation of IProducerConsumerCollection(T) 137 // Demonstrates: 138 // IPCC(T).TryAdd() 139 // IPCC(T).TryTake() 140 // IPCC(T).CopyTo() 141 static void TestSafeStack() 142 { 143 SafeStack<int> stack = new SafeStack<int>(); 144 IProducerConsumerCollection<int> ipcc = (IProducerConsumerCollection<int>)stack; 145 146 // Test Push()/TryAdd() 147 stack.Push(10); Console.WriteLine("Pushed 10"); 148 ipcc.TryAdd(20); Console.WriteLine("IPCC.TryAdded 20"); 149 stack.Push(15); Console.WriteLine("Pushed 15"); 150 151 int[] testArray = new int[3]; 152 153 // Try CopyTo() within boundaries 154 try 155 { 156 ipcc.CopyTo(testArray, 0); 157 Console.WriteLine("CopyTo() within boundaries worked, as expected"); 158 } 159 catch (Exception e) 160 { 161 Console.WriteLine("CopyTo() within boundaries unexpectedly threw an exception: {0}", e.Message); 162 } 163 164 // Try CopyTo() that overflows 165 try 166 { 167 ipcc.CopyTo(testArray, 1); 168 Console.WriteLine("CopyTo() with index overflow worked, and it SHOULD NOT HAVE"); 169 } 170 catch (Exception e) 171 { 172 Console.WriteLine("CopyTo() with index overflow threw an exception, as expected: {0}", e.Message); 173 } 174 175 // Test enumeration 176 Console.Write("Enumeration (should be three items): "); 177 foreach (int item in stack) Console.Write("{0} ", item); 178 Console.WriteLine(""); 179 180 // Test TryPop() 181 int popped = 0; 182 if (stack.TryPop(out popped)) 183 { 184 Console.WriteLine("Successfully popped {0}", popped); 185 } 186 else Console.WriteLine("FAILED to pop!!"); 187 188 // Test Count 189 Console.WriteLine("stack count is {0}, should be 2", stack.Count); 190 191 // Test TryTake() 192 if (ipcc.TryTake(out popped)) 193 { 194 Console.WriteLine("Successfully IPCC-TryTaked {0}", popped); 195 } 196 else Console.WriteLine("FAILED to IPCC.TryTake!!"); 197 } 198 } 199

.NET並行計算和並發11:並發接口 IProducerConsumerCollection