我正在 VS2010 Ultimate 中使用 TPL 构建应用程序。大多数情况下,当我从 UI 线程调用 DoRepresentation() 时,我运行应用程序时它变得无响应。
void DoRepresentation()
{
Parallel.ForEach(cgs, loopOptions, g =>
{
UpdateRepresentation(g);
});
}
void UpdateRepresentation(object g)
{
view.Invoke(new Action(() =>
{
representation = new MyRepresentation(g);
}));
}
我不知道为什么该应用变得无响应。我遇到了僵局吗?
在 MyRepresentation 中,我对 OpenGL 进行了一些调用。
view 是 Form1(主窗体)内的控件。
当应用程序变得无响应时,我从 VS IDE 暂停它,这是我得到的信息
在“并行任务”窗口中,我得到以下信息:
ID Status Message<br>
1 ?Waiting Task1 is waiting on object: "Task2"<br>
2 ?Waiting No waiting information available<br>
在“调用堆栈”窗口中,我得到以下信息:
[In a Sleep, wait, or join]<br>
[External Code]<br>
Test.dll!Render.DoRepresentation()<br>
App1.exe!Form1.Button1_Click<br>
我们将不胜感激。
请您参考如下方法:
是的,你遇到了僵局。 Parallel.ForEach() 的作用是使用一个或多个线程包括当前线程运行迭代,然后阻塞当前线程,直到所有迭代完成。 p>
这意味着如果您从 UI 线程调用 DoRepresentation(),就会出现死锁:UI 线程正在等待其他线程上的迭代完成,而其他线程正在等待 Invoke() 完成,如果 UI 线程被阻塞,则不会发生这种情况。
此外,在您的情况下,使用 Parallel.ForEach() 没有任何意义(假设这是您的实际代码):您运行 new MyRepresentation()在 UI 线程上。
我不明白代码到底在做什么(它似乎在每次迭代中都覆盖了 representation),但我认为你应该运行 ForEach()后台线程。这意味着 DoRepresentation() 将在完成其工作之前返回,因此 Invoke() 将正常工作。
一般而言,长时间阻塞 UI 线程并不是一个好主意,因此您应该在另一个线程上运行任何耗时的代码。
