【问题标题】:Interaction of BindingOperations.EnableCollectionSynchronization and CollectionChanged in multi threaded WPF application多线程 WPF 应用程序中 BindingOperations.EnableCollectionSynchronization 和 CollectionChanged 的​​交互
【发布时间】:2015-01-29 10:45:18
【问题描述】:

我正在尝试开发一个多线程 WPF 应用程序。作为其中的一部分,我正在使用...

BindingOperations.EnableCollectionSynchronization(
                            IEnumerable collection,
                            object context,
                            CollectionSynchronizationCallback synchronizationCallback)

...避免工作线程更新ListView,这将导致异常。

ObservableCollection 在工作线程上引发 CollectionChanged 时,以上将确保转换到 UI 线程。

您可以在synchronizationCallback 中实现自己的锁,如下所示:

protected void synchronizationCallback(
            IEnumerable collection,
            object context,
            Action accessMethod,
            bool writeAccess)
{
    ReaderWriterLockSlim listLock = context as ReaderWriterLockSlim;

    if (writeAccess)
    {
        listLock.EnterWriteLock();

        accessMethod();

        listLock.ExitWriteLock();                

        return;
    }

    listLock.EnterReadLock();

    accessMethod();

    listLock.ExitReadLock();
}

但是为了避免递归锁,我发现我需要在提升CollectionChanged之前退出ObservableCollection锁。

protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
    Debug.Assert(!this.listLock.IsReadLockHeld);
    Debug.Assert(this.listLock.IsWriteLockHeld);

    this.listLock.ExitWriteLock();

    base.OnCollectionChanged(e);

    this.listLock.EnterWriteLock();
}

因此,在synchronizationCallback 遇到锁之前,可能有另一个工作线程进入ObservableCollection。因此,.NET Framework 代码如果需要读取ObservableCollection,最终可能会读取与NotifyCollectionChangedEventArgs 中通知的状态不同的状态。

但是,这是个问题吗?我的想法是否定的,因为 ListView 将更新为以后的状态。

【问题讨论】:

标签: c# wpf multithreading


【解决方案1】:

是的,这是个问题 - 您可能会收到“在 OnCollectionChanged 事件期间无法更改集合”异常,因为在第二个工作线程尝试更改收藏。

【讨论】:

    猜你喜欢
    • 2010-12-09
    • 1970-01-01
    • 2020-05-02
    • 2011-04-13
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多