lock yield return

This commit is contained in:
neuecc 2021-09-08 19:44:27 +09:00
parent 5eff62bb5a
commit 70b0b4a5b4
32 changed files with 403 additions and 303 deletions

View File

@ -66,14 +66,29 @@ namespace ObservableCollections.Internal
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.GetEnumerator(), filter);
foreach (var item in list)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in list.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}
@ -147,7 +162,16 @@ namespace ObservableCollections.Internal
public IEnumerator<(T, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, array.AsEnumerable().GetEnumerator(), filter);
lock (SyncRoot)
{
foreach (var item in array)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

View File

@ -88,7 +88,16 @@ namespace ObservableCollections.Internal
public IEnumerator<(T, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, dict.Select(x => x.Value).GetEnumerator(), filter);
lock (SyncRoot)
{
foreach (var item in dict)
{
if (filter.IsMatch(item.Value.Value, item.Value.View))
{
yield return item.Value;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

View File

@ -13,7 +13,7 @@ namespace ObservableCollections.Internal
readonly Func<T, TView> transform;
readonly Func<T, TKey> identitySelector;
readonly Dictionary<TKey, TView> viewMap; // view-map needs to use in remove.
readonly SortedDictionary<(TView View, TKey Key), (T Value, TView View)> list;
readonly SortedDictionary<(TView View, TKey Key), (T Value, TView View)> dict;
ISynchronizedViewFilter<T, TView> filter;
@ -39,7 +39,7 @@ namespace ObservableCollections.Internal
dict.Add((view, id), (value, view));
viewMap.Add(id, view);
}
this.list = dict;
this.dict = dict;
this.source.CollectionChanged += SourceCollectionChanged;
}
}
@ -50,7 +50,7 @@ namespace ObservableCollections.Internal
{
lock (SyncRoot)
{
return list.Count;
return dict.Count;
}
}
}
@ -60,7 +60,7 @@ namespace ObservableCollections.Internal
lock (SyncRoot)
{
this.filter = filter;
foreach (var (_, (value, view)) in list)
foreach (var (_, (value, view)) in dict)
{
filter.InvokeOnAttach(value, view);
}
@ -74,7 +74,7 @@ namespace ObservableCollections.Internal
this.filter = SynchronizedViewFilter<T, TView>.Null;
if (resetAction != null)
{
foreach (var (_, (value, view)) in list)
foreach (var (_, (value, view)) in dict)
{
resetAction(value, view);
}
@ -92,7 +92,17 @@ namespace ObservableCollections.Internal
public IEnumerator<(T, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.Select(x => x.Value).GetEnumerator(), filter);
lock (SyncRoot)
{
foreach (var item in dict)
{
if (filter.IsMatch(item.Value.Value, item.Value.View))
{
yield return item.Value;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
@ -116,7 +126,7 @@ namespace ObservableCollections.Internal
var value = e.NewItem;
var view = transform(value);
var id = identitySelector(value);
list.Add((view, id), (value, view));
dict.Add((view, id), (value, view));
viewMap.Add(id, view);
filter.InvokeOnAdd(value, view);
}
@ -126,7 +136,7 @@ namespace ObservableCollections.Internal
{
var view = transform(value);
var id = identitySelector(value);
list.Add((view, id), (value, view));
dict.Add((view, id), (value, view));
viewMap.Add(id, view);
filter.InvokeOnAdd(value, view);
}
@ -141,7 +151,7 @@ namespace ObservableCollections.Internal
var id = identitySelector(value);
if (viewMap.Remove(id, out var view))
{
list.Remove((view, id), out var v);
dict.Remove((view, id), out var v);
filter.InvokeOnRemove(v);
}
}
@ -152,7 +162,7 @@ namespace ObservableCollections.Internal
var id = identitySelector(value);
if (viewMap.Remove(id, out var view))
{
list.Remove((view, id), out var v);
dict.Remove((view, id), out var v);
filter.InvokeOnRemove(v);
}
}
@ -166,14 +176,14 @@ namespace ObservableCollections.Internal
var oldKey = identitySelector(oldValue);
if (viewMap.Remove(oldKey, out var oldView))
{
list.Remove((oldView, oldKey));
dict.Remove((oldView, oldKey));
filter.InvokeOnRemove(oldValue, oldView);
}
var value = e.NewItem;
var view = transform(value);
var id = identitySelector(value);
list.Add((view, id), (value, view));
dict.Add((view, id), (value, view));
viewMap.Add(id, view);
filter.InvokeOnAdd(value, view);
@ -193,12 +203,12 @@ namespace ObservableCollections.Internal
case NotifyCollectionChangedAction.Reset:
if (!filter.IsNullFilter())
{
foreach (var item in list)
foreach (var item in dict)
{
filter.InvokeOnRemove(item.Value);
}
}
list.Clear();
dict.Clear();
viewMap.Clear();
break;
default:

View File

@ -1,46 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Threading;
namespace ObservableCollections.Internal
{
internal class SynchronizedEnumerator<T> : IEnumerator<T>
{
bool isDisposed;
readonly object gate;
readonly bool lockTaken;
readonly IEnumerator<T> enumerator;
public SynchronizedEnumerator(object gate, IEnumerator<T> enumerator)
{
this.gate = gate;
this.enumerator = enumerator;
Monitor.Enter(gate, ref lockTaken);
}
public T Current => enumerator.Current;
object IEnumerator.Current => Current;
public bool MoveNext() => enumerator.MoveNext();
public void Reset() => enumerator.Reset();
public void Dispose()
{
if (!isDisposed)
{
isDisposed = true;
try
{
enumerator.Dispose();
}
finally
{
if (lockTaken)
{
Monitor.Exit(gate);
}
}
}
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 08405416bc7c7e04e9bcaa4fa13c875f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,63 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
namespace ObservableCollections.Internal
{
internal class SynchronizedViewEnumerator<T, TView> : IEnumerator<(T, TView)>, IDisposable
{
bool isDisposed;
readonly bool lockTaken;
readonly object gate;
readonly IEnumerator<(T, TView)> enumerator;
readonly ISynchronizedViewFilter<T, TView> filter;
(T, TView) current;
public SynchronizedViewEnumerator(object gate, IEnumerator<(T, TView)> enumerator, ISynchronizedViewFilter<T, TView> filter)
{
this.gate = gate;
this.enumerator = enumerator;
this.filter = filter;
this.current = default;
this.isDisposed = false;
Monitor.Enter(gate, ref lockTaken);
}
public (T, TView) Current => current;
object IEnumerator.Current => Current;
public bool MoveNext()
{
while (enumerator.MoveNext())
{
current = enumerator.Current;
if (filter.IsMatch(current.Item1, current.Item2))
{
return true;
}
}
return false;
}
public void Reset() => throw new NotSupportedException();
public void Dispose()
{
if (!isDisposed)
{
isDisposed = true;
try
{
enumerator.Dispose();
}
finally
{
if (lockTaken)
{
Monitor.Exit(gate);
}
}
}
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 98be7e821cfba26469f0911671fb24b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -103,9 +103,17 @@ namespace ObservableCollections
public IEnumerator<(KeyValuePair<TKey, TValue>, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<KeyValuePair<TKey, TValue>, TView>(SyncRoot,
dict.Select(x => (new KeyValuePair<TKey, TValue>(x.Key, x.Value.Item1), x.Value.Item2)).GetEnumerator(),
filter);
lock (SyncRoot)
{
foreach (var item in dict)
{
var v = (new KeyValuePair<TKey, TValue>(item.Key, item.Value.Item1), item.Value.Item2);
if (filter.IsMatch(v.Item1, v.Item2))
{
yield return v;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -211,7 +211,13 @@ namespace ObservableCollections
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return new SynchronizedEnumerator<KeyValuePair<TKey, TValue>>(SyncRoot, dictionary.GetEnumerator());
lock (SyncRoot)
{
foreach (var item in dictionary)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -280,7 +280,13 @@ namespace ObservableCollections
public IEnumerator<T> GetEnumerator()
{
return new SynchronizedEnumerator<T>(SyncRoot, buffer.GetEnumerator());
lock (SyncRoot)
{
foreach (var item in buffer)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -88,7 +88,16 @@ namespace ObservableCollections
public IEnumerator<(T, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, dict.Select(x => x.Value).GetEnumerator(), filter);
lock (SyncRoot)
{
foreach (var item in dict)
{
if (filter.IsMatch(item.Value.Item1, item.Value.Item2))
{
yield return item.Value;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

View File

@ -247,7 +247,13 @@ namespace ObservableCollections
public IEnumerator<T> GetEnumerator()
{
return new SynchronizedEnumerator<T>(SyncRoot, set.GetEnumerator());
lock (SyncRoot)
{
foreach (var item in set)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -89,14 +89,29 @@ namespace ObservableCollections
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.GetEnumerator(), filter);
foreach (var item in list)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in list.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}

View File

@ -139,7 +139,13 @@ namespace ObservableCollections
public IEnumerator<T> GetEnumerator()
{
return new SynchronizedEnumerator<T>(SyncRoot, list.GetEnumerator());
lock (SyncRoot)
{
foreach (var item in list)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -89,14 +89,29 @@ namespace ObservableCollections
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, queue.GetEnumerator(), filter);
foreach (var item in queue)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, queue.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in queue.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}

View File

@ -203,7 +203,13 @@ namespace ObservableCollections
public IEnumerator<T> GetEnumerator()
{
return new SynchronizedEnumerator<T>(SyncRoot, queue.GetEnumerator());
lock (SyncRoot)
{
foreach (var item in queue)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -90,14 +90,29 @@ namespace ObservableCollections
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, ringBuffer.AsEnumerable().GetEnumerator(), filter);
foreach (var item in ringBuffer)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, ringBuffer.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in ringBuffer.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}

View File

@ -195,7 +195,13 @@ namespace ObservableCollections
public IEnumerator<T> GetEnumerator()
{
return new SynchronizedEnumerator<T>(SyncRoot, buffer.GetEnumerator());
lock (SyncRoot)
{
foreach (var item in buffer)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -89,14 +89,29 @@ namespace ObservableCollections
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, stack.GetEnumerator(), filter);
foreach (var item in stack)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, stack.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in stack.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}

View File

@ -199,7 +199,13 @@ namespace ObservableCollections
public IEnumerator<T> GetEnumerator()
{
return new SynchronizedEnumerator<T>(SyncRoot, stack.GetEnumerator());
lock (SyncRoot)
{
foreach (var item in stack)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -66,14 +66,29 @@ namespace ObservableCollections.Internal
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.GetEnumerator(), filter);
foreach (var item in list)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in list.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}
@ -147,7 +162,16 @@ namespace ObservableCollections.Internal
public IEnumerator<(T, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, array.AsEnumerable().GetEnumerator(), filter);
lock (SyncRoot)
{
foreach (var item in array)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

View File

@ -88,7 +88,16 @@ namespace ObservableCollections.Internal
public IEnumerator<(T, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, dict.Select(x => x.Value).GetEnumerator(), filter);
lock (SyncRoot)
{
foreach (var item in dict)
{
if (filter.IsMatch(item.Value.Value, item.Value.View))
{
yield return item.Value;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

View File

@ -13,7 +13,7 @@ namespace ObservableCollections.Internal
readonly Func<T, TView> transform;
readonly Func<T, TKey> identitySelector;
readonly Dictionary<TKey, TView> viewMap; // view-map needs to use in remove.
readonly SortedDictionary<(TView View, TKey Key), (T Value, TView View)> list;
readonly SortedDictionary<(TView View, TKey Key), (T Value, TView View)> dict;
ISynchronizedViewFilter<T, TView> filter;
@ -39,7 +39,7 @@ namespace ObservableCollections.Internal
dict.Add((view, id), (value, view));
viewMap.Add(id, view);
}
this.list = dict;
this.dict = dict;
this.source.CollectionChanged += SourceCollectionChanged;
}
}
@ -50,7 +50,7 @@ namespace ObservableCollections.Internal
{
lock (SyncRoot)
{
return list.Count;
return dict.Count;
}
}
}
@ -60,7 +60,7 @@ namespace ObservableCollections.Internal
lock (SyncRoot)
{
this.filter = filter;
foreach (var (_, (value, view)) in list)
foreach (var (_, (value, view)) in dict)
{
filter.InvokeOnAttach(value, view);
}
@ -74,7 +74,7 @@ namespace ObservableCollections.Internal
this.filter = SynchronizedViewFilter<T, TView>.Null;
if (resetAction != null)
{
foreach (var (_, (value, view)) in list)
foreach (var (_, (value, view)) in dict)
{
resetAction(value, view);
}
@ -92,7 +92,17 @@ namespace ObservableCollections.Internal
public IEnumerator<(T, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.Select(x => x.Value).GetEnumerator(), filter);
lock (SyncRoot)
{
foreach (var item in dict)
{
if (filter.IsMatch(item.Value.Value, item.Value.View))
{
yield return item.Value;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
@ -116,7 +126,7 @@ namespace ObservableCollections.Internal
var value = e.NewItem;
var view = transform(value);
var id = identitySelector(value);
list.Add((view, id), (value, view));
dict.Add((view, id), (value, view));
viewMap.Add(id, view);
filter.InvokeOnAdd(value, view);
}
@ -126,7 +136,7 @@ namespace ObservableCollections.Internal
{
var view = transform(value);
var id = identitySelector(value);
list.Add((view, id), (value, view));
dict.Add((view, id), (value, view));
viewMap.Add(id, view);
filter.InvokeOnAdd(value, view);
}
@ -141,7 +151,7 @@ namespace ObservableCollections.Internal
var id = identitySelector(value);
if (viewMap.Remove(id, out var view))
{
list.Remove((view, id), out var v);
dict.Remove((view, id), out var v);
filter.InvokeOnRemove(v);
}
}
@ -152,7 +162,7 @@ namespace ObservableCollections.Internal
var id = identitySelector(value);
if (viewMap.Remove(id, out var view))
{
list.Remove((view, id), out var v);
dict.Remove((view, id), out var v);
filter.InvokeOnRemove(v);
}
}
@ -166,14 +176,14 @@ namespace ObservableCollections.Internal
var oldKey = identitySelector(oldValue);
if (viewMap.Remove(oldKey, out var oldView))
{
list.Remove((oldView, oldKey));
dict.Remove((oldView, oldKey));
filter.InvokeOnRemove(oldValue, oldView);
}
var value = e.NewItem;
var view = transform(value);
var id = identitySelector(value);
list.Add((view, id), (value, view));
dict.Add((view, id), (value, view));
viewMap.Add(id, view);
filter.InvokeOnAdd(value, view);
@ -193,12 +203,12 @@ namespace ObservableCollections.Internal
case NotifyCollectionChangedAction.Reset:
if (!filter.IsNullFilter())
{
foreach (var item in list)
foreach (var item in dict)
{
filter.InvokeOnRemove(item.Value);
}
}
list.Clear();
dict.Clear();
viewMap.Clear();
break;
default:

View File

@ -1,63 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
namespace ObservableCollections.Internal
{
internal class SynchronizedViewEnumerator<T, TView> : IEnumerator<(T, TView)>, IDisposable
{
bool isDisposed;
readonly bool lockTaken;
readonly object gate;
readonly IEnumerator<(T, TView)> enumerator;
readonly ISynchronizedViewFilter<T, TView> filter;
(T, TView) current;
public SynchronizedViewEnumerator(object gate, IEnumerator<(T, TView)> enumerator, ISynchronizedViewFilter<T, TView> filter)
{
this.gate = gate;
this.enumerator = enumerator;
this.filter = filter;
this.current = default;
this.isDisposed = false;
Monitor.Enter(gate, ref lockTaken);
}
public (T, TView) Current => current;
object IEnumerator.Current => Current!;
public bool MoveNext()
{
while (enumerator.MoveNext())
{
current = enumerator.Current;
if (filter.IsMatch(current.Item1, current.Item2))
{
return true;
}
}
return false;
}
public void Reset() => throw new NotSupportedException();
public void Dispose()
{
if (!isDisposed)
{
isDisposed = true;
try
{
enumerator.Dispose();
}
finally
{
if (lockTaken)
{
Monitor.Exit(gate);
}
}
}
}
}
}

View File

@ -103,9 +103,17 @@ namespace ObservableCollections
public IEnumerator<(KeyValuePair<TKey, TValue>, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<KeyValuePair<TKey, TValue>, TView>(SyncRoot,
dict.Select(x => (new KeyValuePair<TKey, TValue>(x.Key, x.Value.Item1), x.Value.Item2)).GetEnumerator(),
filter);
lock (SyncRoot)
{
foreach (var item in dict)
{
var v = (new KeyValuePair<TKey, TValue>(item.Key, item.Value.Item1), item.Value.Item2);
if (filter.IsMatch(v.Item1, v.Item2))
{
yield return v;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -88,7 +88,16 @@ namespace ObservableCollections
public IEnumerator<(T, TView)> GetEnumerator()
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, dict.Select(x => x.Value).GetEnumerator(), filter);
lock (SyncRoot)
{
foreach (var item in dict)
{
if (filter.IsMatch(item.Value.Item1, item.Value.Item2))
{
yield return item.Value;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

View File

@ -247,7 +247,13 @@ namespace ObservableCollections
public IEnumerator<T> GetEnumerator()
{
return new SynchronizedEnumerator<T>(SyncRoot, set.GetEnumerator());
lock (SyncRoot)
{
foreach (var item in set)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()

View File

@ -89,14 +89,29 @@ namespace ObservableCollections
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.GetEnumerator(), filter);
foreach (var item in list)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, list.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in list.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}

View File

@ -89,14 +89,29 @@ namespace ObservableCollections
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, queue.GetEnumerator(), filter);
foreach (var item in queue)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, queue.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in queue.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}

View File

@ -90,14 +90,29 @@ namespace ObservableCollections
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, ringBuffer.AsEnumerable().GetEnumerator(), filter);
foreach (var item in ringBuffer)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, ringBuffer.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in ringBuffer.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}

View File

@ -89,14 +89,29 @@ namespace ObservableCollections
}
public IEnumerator<(T, TView)> GetEnumerator()
{
lock (SyncRoot)
{
if (!reverse)
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, stack.GetEnumerator(), filter);
foreach (var item in stack)
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
else
{
return new SynchronizedViewEnumerator<T, TView>(SyncRoot, stack.AsEnumerable().Reverse().GetEnumerator(), filter);
foreach (var item in stack.AsEnumerable().Reverse())
{
if (filter.IsMatch(item.Item1, item.Item2))
{
yield return item;
}
}
}
}
}

View File

@ -199,7 +199,13 @@ namespace ObservableCollections
public IEnumerator<T> GetEnumerator()
{
return new SynchronizedEnumerator<T>(SyncRoot, stack.GetEnumerator());
lock (SyncRoot)
{
foreach (var item in stack)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()