1

我的问题感觉与这篇文章中提到的问题非常相似。本质上,Invoke 是挂起的(仅当在调试器之外运行时)。我认为这是由于 Invoke 调用的嵌套。

我正在使用 MVVM Light,并且我已经尝试了多线程友好的 ObservableCollection 的两种实现——我已经使用这个很久了,最近尝试简化到这个版本。后者似乎更好,直到它因“由该线程拥有”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。

总而言之,我需要回答以下两个问题之一:

  1. 是什么让我的 UI 线程进入等待模式,使得 Invoke 挂起?
  2. 是否有更好的 ObservableCollection 派生类用于此?

谢谢你的思考。

更新

好吧,我不知道是否删除这个问题并重新开始或什么。看来问题与我用来过滤 ReportEntry 的 ListCollectionView 有关。我的 FileViewModel 有一个

public ListCollectionView FilteredReports {get; private set;}

像这样初始化:

FilteredReports = new ListCollectionView(Reports);
FilteredReports.Filter = FilterFunction;

当我删除 FilteredReports 时,不再挂起。烦人的是,我将此视图用作 ItemsSource 的 DataGrid 位于 DataTemplate 中,因此将过滤器移至我的视图也并非易事。那么,ListCollectionView 有什么理由挂在 Collection 更新上?

4

2 回答 2

1

而不是回答让我问。在“应用程序挂起”场景中,您是否尝试过调试器下的“当异常为 CLR 异常时中断”选项?

是的,我仔细阅读了您的帖子,您说它没有挂在调试器(Heisenbug)下。只是想确保没有例外(甚至与绑定或布局相关)。

我问这个是因为在非常罕见的情况下,当发生意外异常时(我认为它们是Mandelbugs),我已经看到 WPF 内部深处的死锁。修复该异常也修复了死锁问题。

于 2009-12-29T17:04:25.327 回答
0

确保您的 ListCollectionView 本身不是在后台线程上创建的。我遇到了同样的问题,并在http://social.msdn.microsoft.com/Forums/en/wpf/thread/410a0b39-dfdb-4115-8a68-4ccabc17bcb6上找到了该建议。我确实这样做了,并确保在 UI 线程上构建 ListCollectionView 解决了我的“挂起”问题。

于 2010-08-01T02:57:07.593 回答