English 中文(简体)
在被阻止的UI线程中处理Windows消息?
原标题:Processing Windows Messages in blocked UI Thread?

这可能与ProgressBar在被阻止的UI线程中更新,但有点不同。

在对崩溃的WinForms控件(DevExpress树列表)进行故障排除时,我们团队的一名成员遇到了一个异常情况,我想知道是否有人能帮助我们了解发生了什么。英语不是他的第一语言,所以我代表他发帖子。

请参阅此屏幕截图来自Visual Studio 2005。

请注意以下几点:

  1. 主UI线程已停止,并且当前处于DevExpress控件绘制方法中。

  2. 屏幕上显示的代码来自同一调用堆栈中较早的一点。此代码位于数据层中,是响应控件对显示树节点的图像的请求而调用的。(可能也源于Paint处理程序)

  3. 显示的代码来自调用堆栈的早期,在主UI线程上,并且当前正在等待锁!由于远程系统可以发送在数据模型中的后台线程上处理的事件(即,数据模型在客户端和服务器之间同步),因此我们锁定以确保数据收集线程的安全。

  4. 正如调用堆栈所示,我们继续在UI线程上处理绘画消息,而我们预计线程会被阻塞。

这很难复制,而且我无法在自己的盒子上使用更简单的测试项目来做到这一点。然而,当出现这种情况时,结果是DevExpress控件的内部状态可能会混乱,导致控件崩溃。这看起来并不是控件中的一个错误,因为毫无疑问,它是在假设这些绘制方法仅在UI线程上运行的情况下编写的。我们在这里看到的使UI线程看起来像两个线程。

这似乎只是调用堆栈表示中的Visual Studio错误,只是这整个工作是由于对已发布的应用程序中控件偶尔发生的崩溃进行了故障排除(在这种情况下,它在UI中显示为一个大的红色X),所以问题似乎并不是孤立于调试环境的。

好吧,这很复杂,但希望有意义。有什么想法吗?

问题回答

我强烈建议不要锁定UI以等待后台处理。考虑一下多重缓冲。使用.NET 4中的线程安全集合,但如果这不是一个选项,则v4之前发布的并行扩展

如何更改同步方案,使您不需要获取独占锁来读取数据?

在这样的情况下,即使在写入数据的同时进行读取,也可以确保读取始终会产生一致的数据,您可能可以不使用getter的锁语句。否则会出现ReaderWriterLockSlim,它允许多个并发读卡器,但仍允许您停止印刷机进行写操作。

它并不能解决所有问题,但至少减少了死锁的机会。

我们在我们的项目中看到了类似的东西。堆栈跟踪看起来像是在UI线程等待锁定时调用泵的事件循环。如果在UI线程上调用Monitor.enter时有一些特殊行为,则可能会发生这种情况。我相信这就是发生的事情,但我还没有找到任何文件来支持它。

可能与同步上下文有关:)





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签