我如何找出调整主窗体大小时长时间延迟的根源?
我有一个 D2006 应用程序,其中包含页面控件和选项卡上的各种网格等。当我调整主窗体的大小(它会影响并调整窗体上与某些内容对齐的所有内容的大小)时,我会遇到很长的延迟,例如几秒钟。应用程序冻结,未调用空闲处理程序,并且正在运行的线程似乎也挂起。
当发生这种情况时,我尝试在 IDE 中暂停执行,试图在遇到麻烦的代码时中断执行,但 IDE 不接收消息。
显然,我并不期望任何人指出我的一些错误代码,但我正在调试可能对我有帮助的方法。我在整个应用程序中有大量的执行计时代码,并且任何数据中都没有显示出长时间的延迟。例如,主窗体 OnResize 处理程序的执行时间是最少的。
I have a D2006 app that contains a page control and various grids, etc on the tabs. When I resize the main form (which ripples through and resizes just about everything on the form that is aligned to something), I experience long delays, like several seconds. The app freezes, the idle handler is not called and running threads appear to suspend also.
I have tries pausing execution in the IDE while this is happening in an attempt to break execution while it is in the troublesome code, but the IDE is not taking messages.
Obviously I'm not expecting anyone to point me at some errant piece of code, but I'm after debugging approaches that might help me. I have extensive execution timing code throughout the app, and the long delays don't show up in any of the data. For example, the execution time of the main form OnResize handler is minimal.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您想了解到底是什么占用了您的时间,请尝试使用分析器。 Sampling Profiler 可以很容易地回答您的问题,特别是如果您能够找到导致问题的代码部分的开头和结尾麻烦并在其周围插入
OutputDebugString
语句以缩小分析范围。If you want to find out what's actually taking up your time, try a profiler. Sampling Profiler could answer your question pretty easily, especially if you're able to find the beginning and the end of the section of code that's causing trouble and insert
OutputDebugString
statements around it to narrow down the profiling.在 AQTime 的性能分析器中运行您的应用程序(包含在 XE 中,但您可以从其网站获取限时版本)。
进行一些疯狂的大小调整一段时间,然后停止应用程序。
之后,您将准确地看到哪个函数被调用了多次,以及大部分时间都花在了哪里。
Run your application in AQTime's performance profiler (included with XE, but you can get a time-limited version from their website).
Do some fanatic resizing for a while, and then stop the application.
After that, you'll see exactly which function was called many times, and where most time was spent.
好的。问题解决了。我注意到只有当我启用命令行开关来记录一些调试信息时才会出现问题。调试信息包括一些写入到选项卡之一上的调试日志(TMemo)的 HTTP 响应。当 HTTP 响应包含没有 CR/LF 的大块时,TMemo 会将其包装起来。每当我调整主窗体的大小时,TMemo 都会调整大小,并且控件必须使用新的自动换行再次呈现文本。
演示:
我不会给自己答案,因为我没有真正提供足够的信息供其他人解决它。
顺便说一句@Mason - SamplingProfiler 会选择这个吗 - 鉴于执行是在 VCL 内部,而不是在我的代码中?
OK. Problem solved. I noticed that the problem only occurred when I had command-line switches enabled to log some debug info. The debug info included some HTTP responses that were written to a debug log (a TMemo) on one of the tabs. When the HTTP response included a large block with no CR/LFs the TMemo wrapped it. Whenever I resized the main form, the TMemo resized and the control had to render the text again with the new word wrapping.
To demonstrate:
I won't award myself the answer, as I hadn't really provided enough info for anybody else to solve it.
BTW @Mason - would SamplingProfiler have picked this one up - given that the execution is inside the VCL, and not in my code?
可能会产生结果的强力方法...将每个调整大小事件中的调试消息放入 OutputDebugString() 中,将控件的名称作为要显示的字符串发送。这可能会向您显示哪些被称为“很多”。
您可能会遇到这样的情况:控件相互碰撞,引发级联调整大小事件。就像紧凑型轿车后座上的 3 个兄弟姐妹一样,一旦他们开始争夺位置,他们可能需要一段时间才能“安定下来”。
不要让我转动这辆车......
调试日志(可在 IDE 中查看,或使用外部 ODS 查看器)可能会向您显示哪些日志造成了最大的麻烦,如果它们对于一个“用户”多次出现-发起调整大小事件”。
A brute-force approach that may give results.... Put a debug message to OutputDebugString() from every re-size event, sending the name of the control as the string to be displayed. This may show you which ones are being called "a lot".
You may have a situation where controls are bumping each other, setting off cascading re-size events. Like 3 siblings in the back seat of a compact car, once they start jostling for position, it can take a while for them to "settle down".
Don't make me turn this car arround....
The debug log (viewable in the IDE, or with an external ODS viewer), may show you which ones are causing the most trouble, if they appear multiple times for one "user-initiated re-size event".