/// <summary> /// Add to a list in a thread safe manner /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="value"></param> public static void ThreadSafeAdd <T>(ref ImmutableLinkedList <T> list, T value) { if (list == null) { throw new ArgumentNullException(nameof(list)); } var listValue = list; var newList = listValue.Add(value); if (ReferenceEquals(Interlocked.CompareExchange(ref list, newList, listValue), listValue)) { return; } var wait = new SpinWait(); while (true) { wait.SpinOnce(); listValue = list; newList = listValue.Add(value); if (ReferenceEquals(Interlocked.CompareExchange(ref list, newList, listValue), listValue)) { return; } } }
/// <summary> /// Empty an immutable linked list in a thread and return the list /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list">list to empty</param> /// <returns></returns> public static ImmutableLinkedList <T> ThreadSafeEmpty <T>(ref ImmutableLinkedList <T> list) { if (list == null) { throw new ArgumentNullException(nameof(list)); } return(Interlocked.Exchange(ref list, ImmutableLinkedList <T> .Empty)); }
/// <summary> /// Add to a list in a thread safe manner /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="value"></param> public static void ThreadSafeAdd <T>(ref ImmutableLinkedList <T> list, T value) { var listValue = list; var newList = listValue.Add(value); if (ReferenceEquals(Interlocked.CompareExchange(ref list, newList, listValue), listValue)) { return; } AddWithWait(ref list, value); }
/// <summary> /// Add a range to a list in a thread safe manner /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="values"></param> public static void ThreadSafeAddRange <T>(ref ImmutableLinkedList <T> list, IEnumerable <T> values) { if (list == null) { throw new ArgumentNullException(nameof(list)); } if (values == null) { throw new ArgumentNullException(nameof(values)); } foreach (var value in values) { ThreadSafeAdd(ref list, value); } }
private static void AddWithWait <T>(ref ImmutableLinkedList <T> list, T value) { ImmutableLinkedList <T> listValue; ImmutableLinkedList <T> newList; var wait = new SpinWait(); while (true) { wait.SpinOnce(); listValue = list; newList = listValue.Add(value); if (ReferenceEquals(Interlocked.CompareExchange(ref list, newList, listValue), listValue)) { return; } } }
public bool MoveNext() { if (_current == null) { if (_start.Next == null) { return(false); } _current = _start; } else if (_current.Next?.Next == null) { return(false); } else { _current = _current.Next; } return(true); }
public void Reset() { _current = _start; }
public LinkedListEnumerator(ImmutableLinkedList <T> current) { _start = current; }
/// <summary> /// Empty an immutable linked list in a thread and return the list /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list">list to empty</param> /// <returns></returns> public static ImmutableLinkedList <T> ThreadSafeEmpty <T>(ref ImmutableLinkedList <T> list) { return(Interlocked.Exchange(ref list, ImmutableLinkedList <T> .Empty)); }