我有一个Windows Forms程序,它承载了几个WPF控件。它是一个测试执行工具。我们遇到了Invoke调用永远不会返回的问题。这是由我们的一位用户编写的测试计划之一。
问题发生在整个程序的不同Invokes中。两个例子:
winForm.Invoke(new Action(() => wpfControl.DataContext = something));
Application.Current.Dispatcher.Invoke(new Action(() => result.Container.Clear()));
调用Invoke的线程永远不会从Invoke返回。我预计GUI线程会出现死锁,但GUI线程执行正常。 有趣的是,所有WinForm控件都表现正常,但没有WPF控件响应用户。其他工作线程似乎都没有被阻止。
有两个问题浮现在脑海中:
编辑:我应该提到这可能是某种竞争条件。很少见,只有在应用程序正常工作一段时间后才会看到。
答案 0 :(得分:2)
我不确切知道发生了什么事,但你这里的信息太少了。您应该获得dotpeek或者反射器,并在WPF内部“循环”中放置一个断点,并查看它为什么不更新/为什么不调用它。
调试中最强大的技术是实际调试内部代码。如果您使用Snoop工具,我会很有兴趣看看会发生什么。
Invoke
本身是非常死锁的好方法。我遇到了自己的死锁,我见过别人遇到它等等。如果可能的话,看看你是否可以逃脱BeginInvoke
。
答案 1 :(得分:1)
您需要通过控件本身调用(dipatch)。
使用此代码wpfControl.InvokeIfRequired(() => wpfControl.DataContext = something);
这个wpfControl.InvokeIfRequired((() => result.Container.Clear())
public static void InvokeIfRequired(this DispatcherControl control, Action operation)
{
if (control.Dispatcher.CheckAccess())
{
operation();
}
else
{
control.Dispatcher.BeginInvoke(DispatcherPriority.Normal, operation);
}
}
答案 2 :(得分:0)
如果我正确理解了这个问题,那么你有一个Windows Forms,你可以在其上托管WPF控件。
首先,你为什么会这样做?
Windows窗体具有窗口控件
WPF具有WPF控件。
最近我读到WPF可以托管WF表单。来源(Pro#WPF 4.5 in C#,4th Edition)
如果我没弄错,WPF控件将在自己的线程中运行。与WF控制相反。这可能会锁定WPF控件。
的Nb。 如果人们至少贬低至少有胆量去讨论原因。