【问题标题】:Custom tracelistener freezing GUI in WPF applicationWPF 应用程序中的自定义跟踪侦听器冻结 GUI
【发布时间】:2011-05-25 05:38:28
【问题描述】:

完全重写了这个问题,因为我现在有更多关于正在发生的事情的信息。

我有一个 customtracelistener,它覆盖 writeline 方法以将字符串添加到自定义 observablecollection。该集合类将所有通知事件分派给 UI 线程,以允许其他线程对其进行更新,并且仍然允许 WPF 数据绑定。

我有一个包含列表框的用户控件。列表框将跟踪侦听器中的 observablecollection 绑定到它的 itemssource。

在我的应用程序启动中,我设置了 windows/usercontrols/viewmodels,并显示了窗口。然后我启动了一个工作线程,该线程运行应用程序所需的一些后端进程。如果后台线程在 UI 线程完成所有用户控件设置和数据绑定之前执行 Trace.WriteLine,我的应用程序就会死锁。

通过在 UI 线程中添加睡眠和其他随机长时间运行的任务和/或延迟启动工作线程以给 UI 线程时间来完成,我已经能够在某种程度上合理地证明这种竞争条件。

我现在正在考虑实施的解决方案是创建一个AppSetupCompleted 方法,该方法启动所有后端进程的工作线程,并将其发送到具有后台优先级的调度程序。理论上,这是否应该延迟工作线程,直到成功设置 WPF 控件和视图模型的所有绑定?

【问题讨论】:

  • 开启捕获所有抛出的异常,看看会发生什么。

标签: c# wpf multithreading tracelistener


【解决方案1】:

对我来说听起来像是死锁或活锁...假设死锁(应用程序冻结时 CPU 低),将调试器附加到应用程序并中断它。查看线程的调用堆栈(UI 和您调用 Trace.WriteLine 的线程)以查看它们锁定的位置。

如果您无法确定这是阻塞,请将调用堆栈添加到您的问题中,这可能有助于我们回答您的问题。

【讨论】:

  • 请原谅我对这种东西不熟悉,但我怎么能去获取各种线程的调用堆栈。通过单步执行代码,我发现工作线程没有阻塞并且可以很好地通过 Trace.WriteLine 调用。它只是锁定了 GUI 线程。
  • 您的回答无疑为我指明了正确的方向。似乎竞争条件与 UI 线程对 observablecollection 进行初始枚举有关,而其他线程正在修改它。正确的解决方案可能是重写 observablecollection 以使其实际上是线程安全的,但是我不确定在不完全重新实现它的情况下是否能够做到这一点。通过为后台任务创建 AppSetupCompleted 方法解决了眼前的问题。然后我以后台优先级调用 begininvoke 并创建一个线程来运行它。
猜你喜欢
  • 2010-10-06
  • 2010-11-26
  • 2018-01-01
  • 1970-01-01
  • 2016-05-12
  • 2015-09-26
  • 1970-01-01
相关资源
最近更新 更多