【发布时间】:2010-08-01 10:57:07
【问题描述】:
我的问题感觉与in this post 提到的问题非常相似。本质上,Invoke 是挂起的(仅当在调试器之外运行时)。我认为这是由于 Invoke 调用的嵌套所致。
我正在使用 MVVM Light,我尝试了多线程友好型 ObservableCollection 的两种实现 - I've used this one for ages,最近尝试简化为 this version。后者似乎更好,直到它因“由该线程拥有”InvalidOperationException 而失败。看着我的前者副本,看起来我在那里吞下了异常。调皮调皮。这将是属性更改“失败”的原因。
这是麻烦的操作流程。几乎在每一点,我都尝试过将东西移到 ui 线程或将它们移出 ui 线程。我已经设法推迟挂起,但代价是属性更改失败。
- 请求来自线程通过 WCF 到主 ViewModel
- 请求被解析(我在后台线程和调用主线程都试过)
- 从数据库中检索到 ReportEntry 对象
- 显示通过 Messenger 请求编辑对话框发送到 UI 的消息。
- 主窗口处理消息,调用 IEditableObject.BeginEdit 并显示编辑对话框。
- 返回时调用 Messenger 回调 Action。
- 现在可以将 ReportEntry 添加到其正确的集合中。 MainViewModel 有一个 FileViewModel 的集合,每个 FileViewModel 都有一个 ReportViewModel 的集合。
- ReportViewModels 通常由 FileViewModel 创建,它监视 FileModel 的集合的 CollectionChanged 事件。我试过绕过这个来避免更多的嵌套,但无济于事。
此时,我的应用程序要么挂起(如果我主要在主线程上运行),要么 CollectionChanged 事件因线程而失败,这取决于我在线程之间移动事物的方式。
根据我附加的调试器,当应用挂起时,它处于从 Invoke 调用的等待状态。
哦,我已经尝试将各种 Invoke 更改为 BeginInvoke。
总而言之,我需要回答以下两个问题之一:
- 是什么让我的 UI 线程进入等待模式,导致 Invoke 挂起?
- 是否有更好的 ObservableCollection 派生类可用于此目的?
感谢您的思考。
更新
好吧,我不知道是要删除这个问题并重新开始还是什么。看来问题与我用来过滤 ReportEntry 的 ListCollectionView 有关。我的 FileViewModel 有一个
public ListCollectionView FilteredReports {get; private set;}
像这样初始化:
FilteredReports = new ListCollectionView(Reports);
FilteredReports.Filter = FilterFunction;
当我删除 FilteredReports 时,不再挂起。烦人的是,我将此视图用作 ItemsSource 的 DataGrid 位于 DataTemplate 中,因此将过滤器移至我的视图也并非易事。那么,ListCollectionView 有什么理由挂在 Collection 更新上?
【问题讨论】:
标签: wpf multithreading dispatcher