我有一个简单的程序,根据每行字的长度对文本文件进行分类,这个程序在我基于XP的旧机器上运行没有问题,现在我在我的新Win7/英特尔酷睿i5机器上运行这个程序,它冻结了整个系统,并在完成工作后恢复正常。
我已经激活了代码,并找到了导致冻结的行
就是这句特别的台词。
caption := IntToStr(i) + '..' + IntTostr(ii);
我把它改成了
caption := IntTostr(ii); //slow rate change
而且也不会冻结
然后我把它改成了
caption := IntTostr(i); //fast rate change
然后它又结冰了
我的程序代码是
var tword : widestring;
i,ii,li : integer;
begin
tntlistbox1.items.LoadFromFile('d:new folderch.txt');
tntlistbox2.items.LoadFromFile('d:new folderuy.txt');
For ii := 15 Downto 1 Do //slow change
Begin
For I := 0 To TntListBox1.items.Count - 1 Do //very fast change
Begin
caption := IntToStr(i) + '..' + IntTostr(ii); //problemetic line
tword := TntListBox1.items[i];
LI := Length(tword);
If lI = ii Then
Begin
tntlistbox3.items.Add(Trim(tntlistbox1.Items[i]));
tntlistbox4.items.Add(Trim(tntlistbox2.Items[i]));
End;
End;
End;
end;
知道为什么吗?以及如何修复它?我使用Delphi 2007/Win32
3条答案
按热度按时间utugiqy61#
这是否发生在窗体上的事件处理程序中?我猜是这样的。在这种情况下,“标题”在表单的范围内。表单的标题文本不是由VCL管理的,而是由Windows管理的,如果您在每次循环迭代时发送新的WM_SETTEXT消息。
要彻底解释它为什么会这样做,我需要了解Windows的内部结构,但如果我猜一猜,我会说它是这样的:
每次发送带有新标题的WM_SETTEXT邮件时,Windows都会检查以确保它与现有标题不相同。如果是,它可以立即退出。这就是不频繁的更改(只使用
ii
的更改)不会降低系统速度的原因。但如果它确实在每次迭代中发生变化,那么Windows必须执行某种类型的任务切换才能更改它。至于为什么这会在Vista内核(包括Win7)下使整个系统陷入困境,而不是XP,这完全超出了我的专业领域。但是,如果您试图将其作为某种进度指标,那么还有更好的方法,特别是如果这个循环像看起来那样紧密的话。
在紧密循环中处理进度更新的最佳方法是计算迭代次数,并且每X次仅触发一次。(对于X来说,100或1000可能是很好的值,这取决于它运行的次数和整个过程的速度。)这基本上就是
ii
选项执行的操作。您还可以尝试在表单上放置进度条来衡量进度,而不是通过表单的标题来衡量进度。hm2xizp92#
更改窗体的标题会释放一大堆操作--尤其是在激活了Aero的Vista和Win7下。
一个简单的尝试是使用TLabel来显示进度。像这样的东西
应该做到这一点,除非你的标签是透明的或在玻璃区域。
最好是听从梅森·惠勒的建议,使用进度条。因为迭代的总次数是
15*TntListBox1.items.Count
,所以可以很容易地计算进度值。bxgwgixi3#
首先:您忘记了tntlistbox3.items.BeginUpdate/tntlistbox3.items.EndUpdate调用(tntlistbox4也是如此)。
第二名:Why does my program run faster if I click and hold the caption bar?
解决方案(示例):