WinForms中的WPF:虽然UI线程处于活动状态,但在Dispatcher.Invoke上被阻止

时间:2012-09-03 08:46:56

标签: c# .net wpf user-interface freeze

我们在WinForms控件中嵌入了一个WPF控件,该控件又作为ActiveX控件公开。此ActiveX最终用于由第三方开发的C ++应用程序中。

在某些时候,ActiveX控件的UI变得冻结,而其余的C ++应用程序运行正常。经过一些调试后,我注意到每次调用Application.Current.Dispatcher.Invoke时都阻止了WPF控件。但是,WinForms控件处理它的Control.Invoke调用就好了。每当我暂停调试器时,我都可以看到UI线程在C ++应用程序中做了一些工作,但似乎没有阻塞或等待任何事情。就好像UI线程突然并且莫名其妙地拒绝执行WPF委托。

当C ++应用程序在很长一段时间(几分钟)内独占UI线程时,WPF控件有时会进入此状态。我要做的第一件事就是使用不同的线程进行这样一个耗时的任务,但正如我已经说过的,我不对C ++应用程序正在做什么负责。无论如何,这不是我的WPF控件以这种方式运行的原因。我不知道如何解决这个问题;任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

我建议运行MS调试诊断工具 - http://support.microsoft.com/kb/2580960

我们已经有了很好的结果来识别COM互操作阻塞问题,在我们的情况下,这是一个挂起的COM终结器阻塞垃圾收集。您可以在各种模式下运行它,但是当使用.NET分析运行时,它将突出显示终结器队列等的任何问题。运行起来有点笨拙,但它给你的信息是黄金。

答案 1 :(得分:0)

Invoke的问题在于它的行为类似于多线程调用;但事实并非如此,Invoke正在阻止 - 你仍然只是一次让一个线程。 Invoke确实只是确保在UI线程上执行操作。这是通过将消息强制转换为消息泵并以此方式执行来完成的。对于调用Invoke的线程需要执行的操作可能会阻止该操作。 例如:

lock(someLock)
{
    dispatcher.Invoke(SomeMethod);
}

//...

public void SomeMethod()
{
  lock(someLock)
  {
  //... do some work here
  }
}

在此示例中,Invoke在锁定时阻止调用SomeMethod。但是,SomeMethod想要相同的lock,因此它会被阻止等待lock。你有一个僵局。

我建议改用BeginInvoke

我不确定这是你的问题,因为你没有提供任何代码;但这是Invoke非常常见问题。通常没有理由需要Invoke;如果您认为有需要,那通常表明存在问题。

相关问题