需要一个相对线程安全的ObservableCollection
参考
以及结合
https://stackoverflow.com/questions/23108045/how-to-make-observablecollection-thread-safe#
此外吐槽一下,原很久没登的一个老CSDN账号丢了
public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
{
readonly ReaderWriterLockSlim lockSlim = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
//base.OnCollectionChanged(e);
NotifyCollectionChangedEventHandler notifyCollectionChangedEventHandler = this.CollectionChanged;
if (notifyCollectionChangedEventHandler != null)
{
foreach (NotifyCollectionChangedEventHandler handler in notifyCollectionChangedEventHandler.GetInvocationList())
{
DispatcherObject dispatcherObject = handler.Target as DispatcherObject;
if (dispatcherObject != null)
{
Dispatcher dispatcher = dispatcherObject.Dispatcher;
if (dispatcher != null && !dispatcher.CheckAccess())
{
dispatcher.BeginInvoke((Action)(() => handler.Invoke(this,
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))),
DispatcherPriority.DataBind);
continue;
}
}
handler.Invoke(this, e);
}
}
}
protected override void SetItem(int index, T item)
{
lockSlim.EnterWriteLock();
try
{
base.SetItem(index, item);
}
finally
{
lockSlim.ExitWriteLock();
}
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (!lockSlim.IsWriteLockHeld)
{
lockSlim.EnterReadLock();
}
try
{
base.OnPropertyChanged(e);
}
finally
{
if (!lockSlim.IsWriteLockHeld)
{
lockSlim.ExitReadLock();
}
}
}
protected override void InsertItem(int index, T item)
{
lockSlim.EnterWriteLock();
try
{
base.InsertItem(index, item);
}
finally
{
lockSlim.ExitWriteLock();
}
}
protected override void RemoveItem(int index)
{
lockSlim.EnterWriteLock();
try
{
base.RemoveItem(index);
}
finally
{
lockSlim.ExitWriteLock();
}
}
protected override void MoveItem(int oldIndex, int newIndex)
{
lockSlim.EnterWriteLock();
try
{
base.MoveItem(oldIndex, newIndex);
}
finally
{
lockSlim.ExitWriteLock();
}
}
protected override void ClearItems()
{
lockSlim.EnterWriteLock();
try
{
base.ClearItems();
}
finally
{
lockSlim.ExitWriteLock();
}
}
public override bool Equals(object obj)
{
if (!lockSlim.IsWriteLockHeld)
{
lockSlim.EnterReadLock();
}
try
{
return base.Equals(obj);
}
finally
{
if (!lockSlim.IsWriteLockHeld)
{
lockSlim.ExitReadLock();
}
}
}
public override int GetHashCode()
{
if (!lockSlim.IsWriteLockHeld)
{
lockSlim.EnterReadLock();
}
try
{
return base.GetHashCode();
}
finally
{
if (!lockSlim.IsWriteLockHeld)
{
lockSlim.ExitReadLock();
}
}
}
}