C# WM_油漆在并行时如何处理。因为尚未完成?

C# WM_油漆在并行时如何处理。因为尚未完成?,c#,.net,multithreading,blocking,ui-thread,C#,.net,Multithreading,Blocking,Ui Thread,在这样的程序中有一些非最佳代码(让您了解一些伪代码): 有时,程序崩溃,表示位图已被锁定。我不需要调试帮助,也不需要代码来修复问题。我可以很容易地修好它 更让我烦恼的是,我不明白这是怎么发生的。UI线程被阻止的原因。在执行按钮1\u click方法时,不应处理任何windows消息。当然,除非有人调用DoEvents(),情况并非如此 但是,当我查看调用堆栈时,它显示了以下内容: 如您所见,Parallel.For()调用仍然在堆栈上。它还没有完成。.NET代码到达ManualResetEve

在这样的程序中有一些非最佳代码(让您了解一些伪代码):

有时,程序崩溃,表示位图已被锁定。我不需要调试帮助,也不需要代码来修复问题。我可以很容易地修好它

更让我烦恼的是,我不明白这是怎么发生的。UI线程被阻止的原因。在执行
按钮1\u click
方法时,不应处理任何windows消息。当然,除非有人调用
DoEvents()
,情况并非如此

但是,当我查看调用堆栈时,它显示了以下内容:

如您所见,
Parallel.For()
调用仍然在堆栈上。它还没有完成。.NET代码到达ManualResetEventSlim,应等待。从中,我看不到
Wait()
方法执行消息调度

但是,此时处理了一条
WM_PAINT
消息,导致图片框访问位图,而位图仍被
LockBits()锁定

这是怎么回事?我对UI线程阻塞的理解哪里错了


询问这是否仅在调试期间发生。事实上,这似乎是真的。我给了它10次,但它从未崩溃。看来这次调试器不是我的朋友。

有几种方法可以实现这一点:

当你在等待的时候,一些信息仍然在发送。这包括调试程序似乎也使用的COM消息。
自.NET4.0以来,Windows窗体和WPF的消息泵送行为发生了多次更改。如果您有挂起的已发布消息,则通过UI自动化库调用您的应用程序时,它会随时影响您的应用程序。

这是否仅在您处于VS调试器中时才会发生?我注意到调用是通过
DebuggableCallback
进行的,我认为它是由Visual Studio本身调用的,当您的程序运行时没有附加调试器时不会调用它。顺便说一句,我会将
someBitmap.UnlockBits
调用放在
finally
块中。@Dai:看来您是对的。它不会在调试器之外发生(至少在我刚才尝试的最后6次运行中是如此)哦,天哪。。。我不知道,不客气。我在调试那些东西上有我的份;-)。这里还有更糟糕的问题。
public void button1_click()
{
     picturebox1.Image = someBitmap;
     someBitmap.LockBits(...);
     Parallel.For(..., () => DoSomethingWith(someBitmap));
     someBitmap.UnlockBits(...);
}