【问题标题】:Dispatcher.Invoke hanging when ListCollectionView is monitoring CollectionListCollectionView 监控 Collection 时 Dispatcher.Invoke 挂起
【发布时间】: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。

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

  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 更新上?

【问题讨论】:

    标签: wpf multithreading dispatcher


    【解决方案1】:

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

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

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

    【讨论】:

    • 好吧,不幸的是,此时我有很多异常,以至于在抛出时很难运行。我现在已经解决了这个问题(试图在年底之前完成构建),但我确实希望回来再次尝试 viewmodel 路线。这将是我调试的第一步。
    • 没有例外,不知道发生了什么。然而,它不再是海森堡。它只是简单地挂起。我似乎以某种方式使应用程序陷入僵局。我认为我的 CollectionView 的行为应该与我的 wpf 工具包数据网格创建的基本相同。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      • 2019-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-28
      相关资源
      最近更新 更多