v10.10.2024.0701 使用IJsonHost改进Json序列化
大石头 编写于 2024-07-01 08:36:34 大石头 提交于 2024-07-01 08:48:33
X
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;

namespace System.Collections.Concurrent;

[DebuggerTypeProxy(typeof(CollectionDebuggerView<>))]
[DebuggerDisplay("Count={Count}")]
public class ConcurrentQueue<T> : IProducerConsumerCollection<T>, IEnumerable<T>, ICollection, IEnumerable
{
	private class Node
	{
		public T Value;

		public Node Next;
	}

	private class NodeObjectPool : ObjectPool<Node>
	{
		protected override Node Creator()
		{
			return new Node();
		}
	}

	private Node head = new Node();

	private Node tail;

	private int count;

	private static readonly NodeObjectPool pool = new NodeObjectPool();

	private object syncRoot = new object();

	bool ICollection.IsSynchronized => true;

	object ICollection.SyncRoot => syncRoot;

	public int Count => count;

	public bool IsEmpty => count == 0;

	private static Node ZeroOut(Node node)
	{
		node.Value = default(T);
		node.Next = null;
		return node;
	}

	public ConcurrentQueue()
	{
		tail = head;
	}

	public ConcurrentQueue(IEnumerable<T> collection)
		: this()
	{
		foreach (T item in collection)
		{
			Enqueue(item);
		}
	}

	public void Enqueue(T item)
	{
		Node node = pool.Take();
		node.Value = item;
		Node node2 = null;
		Node node3 = null;
		bool flag = false;
		while (!flag)
		{
			node2 = tail;
			node3 = node2.Next;
			if (tail == node2)
			{
				if (node3 == null)
				{
					flag = Interlocked.CompareExchange(ref tail.Next, node, null) == null;
				}
				else
				{
					Interlocked.CompareExchange(ref tail, node3, node2);
				}
			}
		}
		Interlocked.CompareExchange(ref tail, node, node2);
		Interlocked.Increment(ref count);
	}

	bool IProducerConsumerCollection<T>.TryAdd(T item)
	{
		Enqueue(item);
		return true;
	}

	public bool TryDequeue(out T result)
	{
		result = default(T);
		bool flag = false;
		while (!flag)
		{
			Node node = head;
			Node node2 = tail;
			Node next = node.Next;
			if (node != head)
			{
				continue;
			}
			if (node == node2)
			{
				if (next != null)
				{
					Interlocked.CompareExchange(ref tail, next, node2);
				}
				result = default(T);
				return false;
			}
			result = next.Value;
			flag = Interlocked.CompareExchange(ref head, next, node) == node;
			if (flag)
			{
				pool.Release(ZeroOut(node));
			}
		}
		Interlocked.Decrement(ref count);
		return true;
	}

	public bool TryPeek(out T result)
	{
		if (IsEmpty)
		{
			result = default(T);
			return false;
		}
		Node next = head.Next;
		result = next.Value;
		return true;
	}

	internal void Clear()
	{
		count = 0;
		tail = (head = new Node());
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return InternalGetEnumerator();
	}

	public IEnumerator<T> GetEnumerator()
	{
		return InternalGetEnumerator();
	}

	private IEnumerator<T> InternalGetEnumerator()
	{
		Node my_head = head;
		while (true)
		{
			Node next;
			my_head = (next = my_head.Next);
			if (next != null)
			{
				yield return my_head.Value;
				continue;
			}
			break;
		}
	}

	void ICollection.CopyTo(Array array, int index)
	{
		if (array is T[] array2)
		{
			CopyTo(array2, index);
		}
	}

	public void CopyTo(T[] array, int index)
	{
		IEnumerator<T> enumerator = InternalGetEnumerator();
		int num = index;
		while (enumerator.MoveNext())
		{
			array[num++] = enumerator.Current;
		}
	}

	public T[] ToArray()
	{
		T[] array = new T[count];
		CopyTo(array, 0);
		return array;
	}

	bool IProducerConsumerCollection<T>.TryTake(out T item)
	{
		return TryDequeue(out item);
	}
}