【问题标题】:How to find why win32 dialog drawing hangs?如何找到win32对话框绘图挂起的原因?
【发布时间】:2014-12-19 10:23:08
【问题描述】:

我有一个 win32 应用程序,它可以非常快地更新对话框中的许多矩形。 (现在通过bitblt(有点双缓冲),在它是一种不同的方法之前——没关系)。

经过随机时间后 - 随机对话框(来自该应用程序,带有更新的矩形)只是挂在我的电脑上。通过挂起,我的意思是它的重绘挂起,如果我按下一个菜单按钮,它会弹出一些它可以工作的东西,但对话框没有显示任何东西,只是卡住了。它会一直卡住,直到调整大小!或应用程序重新启动,ofc。

这只发生在我的带有 3 个桌面的“快速”PC 上(通过不同的 GPU 控制)。 我的“慢”笔记本电脑无法重现此问题,或者由于速度较慢,可能需要更多时间来重现此问题(不是一夜)?

我真的是 C++ 的新手,Windows 对话框编程 - 我可能会误用某些东西或做错了什么。我检查了一切,重新访问了有关对话框(和每个绘图功能)使用的微软教程,检查了所有内容 - 没有找到任何东西。

也许有人可以为我提供比禁用随机功能更聪明的东西,然后等待它会挂起还是不挂起?我想了解它为什么会崩溃(挂起),以及为什么会这样。

操作系统:Microsoft Windows 7 64 编译器:Visual Studio 2013

补充:调试器停止时:主线程只显示主对话框的入口。 DialogBox 函数,仅此而已。 Ofc 该线程正在运行所有其他对话框,但这些对话框是从 DialogBox 调用的主对话框运行的。绘图是由不同的线程完成的,它甚至没有注意到对话框被挂起。主线程不会“挂起”,因为其他对话框运行得很好。如果调整大小,那个“挂起”的对话框是固定的,太奇怪了。

不同线程绘制方式:对话框由主线程运行,其他线程(实际上是几个线程,优先级低于其他线程)负责biblt和其他对话框的绘制逻辑操作(最多600个矩形)可以更新到100Hz,它很好地吸引了CPU)。我确实解决了关键部分的问题和资源在没有很好使用时释放的问题,但我要做的第一件事就是重新检查这些问题。

【问题讨论】:

  • 如果不发布重现问题的代码,我认为您不会得到这个问题的答案。
  • 调试它。一旦挂起,就硬中断调试器。由于您没有提供代码,因此您将得到的最好的结果是 wags (wild-ass-guesses)。
  • @Arnas - 很少使用对话。此外,在执行您所描述的事情之前,Windows API 编程通常需要大量经验。任何错误的举动,程序将无法正确或一致地运行。如果您没有经验,那么无论您将阅读多少教程,您都不会知道要寻找什么。最好把代码贴在某个地方,让有经验的 Windows 程序员看看。
  • 从创建它们的不同线程访问 Windows 是自找麻烦,即使它只是绘图并且您同步所有内容。您应该从工作线程中绘制到内存后台缓冲区中,然后通知 GUI 线程,然后 GUI 线程应该对窗口执行 blitblt。
  • 我的建议是使用内存位图作为后台缓冲区。所有抽屉线程都将 blt-write 写入其中,主线程将从 blt-read 中读取。绘制完线程会PostMessage()通知主线程。您可以使用简单的互斥锁来同步对 BMP 的访问。你也可以尝试做不同步的 blt-ing 看看会发生什么,也许如果矩形不重叠,它就会工作......

标签: c++ winapi


【解决方案1】:

您根本不应该从其他线程中提取。

然而,单个线程绘制位图(即在内存中)是安全的,然后将该位图交给主线程进行位图处理。从某种意义上说,这可以扩展,您可以让多个线程准备多个位图,并让主线程依次对每个位图进行 bitblt。

【讨论】:

  • 这可能是问题所在,@rodrigo 在 cmets 中首先提到了它。有没有办法“正确”同步两个线程之间的绘图?顺便说一句,微软没有提到任何关于不同线程的 msdn.microsoft.com/en-us/library/windows/desktop/…... 真可惜
  • @Arnas:那会相当冗长,因为他们必须为每个绘图函数添加相同的限制。这个概念被称为thread affinity,每个窗口只关联一个线程(但不同的窗口显然可以关联不同的线程,甚至不同的进程)
猜你喜欢
  • 1970-01-01
  • 2012-11-05
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 1970-01-01
相关资源
最近更新 更多