33 namespace System.Collections.Concurrent
36 [
System.Diagnostics.DebuggerDisplay (
"Count = {Count}")]
37 [
System.Diagnostics.DebuggerTypeProxy (typeof (CollectionDebuggerView<>))]
39 ICollection, IEnumerable
43 public T Value =
default (T);
44 public Node Next = null;
57 foreach (T item
in collection)
69 Node temp =
new Node ();
73 }
while (
AotInterlocked.CompareExchange (ref head, temp, temp.Next) != temp.Next);
75 Interlocked.Increment (ref count);
80 PushRange (items, 0, items.Length);
83 public void PushRange (T[] items,
int startIndex,
int count)
88 for (
int i = startIndex; i < count; i++) {
89 Node temp =
new Node ();
90 temp.Value = items[i];
100 }
while (
AotInterlocked.CompareExchange (ref head, insert, first.Next) != first.Next);
102 Interlocked.Add (ref count, count);
112 result =
default (T);
115 }
while (
AotInterlocked.CompareExchange (ref head, temp.Next, temp) != temp);
117 Interlocked.Decrement (ref count);
127 throw new ArgumentNullException (
"items");
128 return TryPopRange (items, 0, items.Length);
134 throw new ArgumentNullException (
"items");
135 if (startIndex < 0 || startIndex >= items.Length)
136 throw new ArgumentOutOfRangeException (
"startIndex");
138 throw new ArgumentOutOfRangeException (
"count");
139 if (startIndex + count > items.Length)
140 throw new ArgumentException (
"startIndex + count is greater than the length of items.");
150 for (
int j = 0; j < count; j++) {
155 }
while (
AotInterlocked.CompareExchange (ref head, end, temp) != temp);
158 for (i = startIndex; i < startIndex + count && temp != null; i++) {
159 items[i] = temp.Value;
163 Interlocked.Add (ref this.count, -(i - startIndex));
165 return i - startIndex;
171 if (myHead == null) {
172 result =
default (T);
175 result = myHead.Value;
186 IEnumerator IEnumerable.GetEnumerator ()
188 return (IEnumerator)InternalGetEnumerator ();
193 return InternalGetEnumerator ();
196 IEnumerator<T> InternalGetEnumerator ()
199 if (my_head == null) {
203 yield
return my_head.Value;
204 }
while ((my_head = my_head.Next) != null);
208 void ICollection.CopyTo (Array array,
int index)
211 throw new ArgumentNullException (
"array");
213 throw new ArgumentException (
"The array can't be multidimensional");
214 if (array.GetLowerBound (0) != 0)
215 throw new ArgumentException (
"The array needs to be 0-based");
217 T[] dest = array as T[];
219 throw new ArgumentException (
"The array cannot be cast to the collection element type",
"array");
220 CopyTo (dest, index);
223 public void CopyTo (T[] array,
int index)
226 throw new ArgumentNullException (
"array");
228 throw new ArgumentOutOfRangeException (
"index");
229 if (index >= array.Length)
230 throw new ArgumentException (
"index is equals or greather than array length",
"index");
232 IEnumerator<T> e = InternalGetEnumerator ();
234 while (e.MoveNext ()) {
235 if (i == array.Length - index)
236 throw new ArgumentException (
"The number of elememts in the collection exceeds the capacity of array",
"array");
237 array[i++] = e.Current;
241 bool ICollection.IsSynchronized {
247 return TryPop (out item);
250 object syncRoot =
new object ();
251 object ICollection.SyncRoot {
252 get {
return syncRoot; }
257 return new List<T> (
this).ToArray ();
266 public bool IsEmpty {
bool TryPop(out T result)
int TryPopRange(T[] items, int startIndex, int count)
bool TryPeek(out T result)
void PushRange(T[] items, int startIndex, int count)
int TryPopRange(T[] items)
Interlocked reference exchanges do not work with the older Mono AOT compiler so this type fudges arou...
void CopyTo(T[] array, int index)
IEnumerator< T > GetEnumerator()
ConcurrentStack(IEnumerable< T > collection)
void PushRange(T[] items)