微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何处理 WPF 数据库应用程序中的调度程序问题?

如何解决如何处理 WPF 数据库应用程序中的调度程序问题?

我正在开发一个应用程序(使用 C# 和 WPF),为 sql 数据库提供用户界面。应用程序的多个实例同时访问和修改数据库,因此应用程序定期从数据库中请求自上次请求以来修改过的记录,并使用 XML 反序列化将这些记录加载到复杂类的列表中。

通过将列表绑定到 WPF 的 ListView 控件的 ItemsSource 属性,将列表呈现给用户。这最初效果很好,但是当列表更新时(特别是添加删除项目时),我收到此错误

“这种类型的 CollectionView 不支持从不同于 dispatcher 线程的线程更改其 SourceCollection。”

我明白了这个问题,UI线程想通过ListView的调度器的安全性来控制绑定的数据集和添加删除数据。但是,似乎必须有一种方法可以使数据的线程安全 UI 不是单个用户独有的。

我尝试了各种不同类型的集合,包括 ObservableCollectionConcurrentBag,但它们都存在相同的问题。

我可以通过绑定到列表的副本 (List.ToList<>()) 来规避该问题,并在列表更新时使用事件触发重新绑定到新副本,但这看起来很笨拙ListViews 和绑定的目的,远非 C# 或 WPF 的优雅。

我是否遗漏了一些明显的东西?感谢您的帮助!

解决方法

有时 BindingOperations.EnableCollectionSynchronization 可以提供帮助。

Documentation

它使 CollectionView 对象能够参与对在多个线程上使用的集合的同步访问。

BindingOperations.EnableCollectionSynchronization(collection,lockObject);

要在多个线程上使用集合,其中之一是拥有 ItemsControl 的 UI 线程,您必须在访问集合时实例化一个对象以锁定。

调用 EnableCollectionSynchronization(IEnumerable,Object) 以通知 WPF 您正在使用简单的锁定机制。调用必须发生在 UI 线程上。

调用必须在不同线程上使用集合之前或在将集合附加到 ItemsControl 之前发生,以较晚者为准。

通常,我在视图模型的构造函数中调用 BindingOperations.EnableCollectionSynchronization(collection,lockObject)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。