在 Parallel.For 尚未完成时如何处理 WM_PAINT?
How does the WM_PAINT get processed while Parallel.For is not finished yet?
像这样的程序中有一些非最佳代码(伪代码给你一个想法):
public void button1_click()
{
picturebox1.Image = someBitmap;
someBitmap.LockBits(...);
Parallel.For(..., () => DoSomethingWith(someBitmap));
someBitmap.UnlockBits(...);
}
程序时不时崩溃,说位图已经被锁定。我不需要调试帮助,也不需要代码来解决问题。我可以轻松修复它。
更让我困扰的是我不明白这是怎么发生的。恕我直言,UI 线程被阻塞。在执行 button1_click
方法时,不应处理任何 windows 消息。当然,除非有人打电话给DoEvents()
,否则不是这样。
不过,当我查看调用堆栈时,它显示如下:
如您所见,Parallel.For()
调用仍在堆栈中。它还没有完成。 .NET 代码达到了 ManualResetEventSlim,应该等待。从 MSDN 我看不到 Wait()
方法进行消息调度。
不过,在那一点上,一条 WM_PAINT
消息得到处理,导致图片框访问位图,而该位图仍被 LockBits()
锁定。
这是怎么回事?我对UI线程阻塞的理解哪里错了?
@Dai 询问这是否仅在调试期间发生。确实,这似乎是真的。我给它运行了 10 次,它从未崩溃过。看来调试器这次不是我的朋友了
有几种方法可以实现:
当您等待时,一些消息仍会被发送。这包括似乎也被调试器使用的 COM 消息。
自 .NET 4.0 以来,Windows Forms 和 WPF 的消息泵送行为发生了多次变化。如果您通过 UI 自动化库调用,如果您有未决的已发布消息,它可以随时访问您的应用程序。
像这样的程序中有一些非最佳代码(伪代码给你一个想法):
public void button1_click()
{
picturebox1.Image = someBitmap;
someBitmap.LockBits(...);
Parallel.For(..., () => DoSomethingWith(someBitmap));
someBitmap.UnlockBits(...);
}
程序时不时崩溃,说位图已经被锁定。我不需要调试帮助,也不需要代码来解决问题。我可以轻松修复它。
更让我困扰的是我不明白这是怎么发生的。恕我直言,UI 线程被阻塞。在执行 button1_click
方法时,不应处理任何 windows 消息。当然,除非有人打电话给DoEvents()
,否则不是这样。
不过,当我查看调用堆栈时,它显示如下:
如您所见,Parallel.For()
调用仍在堆栈中。它还没有完成。 .NET 代码达到了 ManualResetEventSlim,应该等待。从 MSDN 我看不到 Wait()
方法进行消息调度。
不过,在那一点上,一条 WM_PAINT
消息得到处理,导致图片框访问位图,而该位图仍被 LockBits()
锁定。
这是怎么回事?我对UI线程阻塞的理解哪里错了?
@Dai 询问这是否仅在调试期间发生。确实,这似乎是真的。我给它运行了 10 次,它从未崩溃过。看来调试器这次不是我的朋友了
有几种方法可以实现:
当您等待时,一些消息仍会被发送。这包括似乎也被调试器使用的 COM 消息。 自 .NET 4.0 以来,Windows Forms 和 WPF 的消息泵送行为发生了多次变化。如果您通过 UI 自动化库调用,如果您有未决的已发布消息,它可以随时访问您的应用程序。