WPF线程安全的ObservableCollection

需要一个相对线程安全的ObservableCollection

参考

 https://github.com/piercep/thread-safe-collections/blob/master/ThreadSafeCollections/ThreadSafeCollections/TList.cs

以及结合

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();
                }
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/ilikeff8/article/details/85318106
今日推荐