4

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

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

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

4

2 回答 2

1

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

我们使用它来识别 COM 互操作阻塞问题取得了很好的结果,在我们的案例中,这些问题归结为待处理的 COM 终结器阻塞垃圾收集。您可以在各种模式下运行它,但是当使用 .NET 分析运行时,它会突出显示终结器队列等的任何问题。运行起来有点笨拙,但它为您提供的信息是黄金。

于 2012-10-05T18:29:05.943 回答
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;如果您认为有需要,这通常表明存在问题。

于 2012-09-05T16:23:59.273 回答