delphi app冻结整个win7系统

时间:2010-06-16 05:57:33

标签: delphi windows-7 freeze

我有一个简单的程序,可以根据每行的单词长度对文本文件进行排序 这个程序在我的基于xp的旧机器上运行没有问题 现在我在我的新win7 / intel核心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 folder\ch.txt');
     tntlistbox2.items.LoadFromFile('d:\new folder\uy.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 个答案:

答案 0 :(得分:10)

这是否发生在表单上的事件处理程序中?我猜它会是的。在这种情况下,“标题”在表格的范围内。表单的标题文本不是由VCL管理,而是由Windows管理,如果您在循环的每次迭代中发送新的WM_SETTEXT消息。

彻底解释为什么这样做正在做的事情需要了解我没有的Windows内部知识,但是如果我要猜测,我会说它是这样的:

每次发送带有新标题的WM_SETTEXT消息时,Windows都会检查以确保它与现有标题不同。如果是,它可以立即退出。这就是为什么不频繁的更改(仅使用ii)不会减慢系统速度的原因。但如果它在每次迭代中都发生了变化,那么Windows必须执行某种任务切换才能进行更改。

至于为什么会在Vista内核(包括Win7)而不是XP下陷入整个系统,这完全超出了我的专业领域。但是如果你试图将其作为某种进度指示器,那么有更好的方法,特别是如果这个循环像它看起来那么紧。

在紧密循环中处理进度更新的最佳方法是计算迭代次数,并且每X次只触发一次。 (100或1000可以是X的良好值,取决于它运行的次数和整个事物的速度。)这基本上是ii唯一选项的作用。您还可以尝试在表单上放置一个进度条来衡量进度,而不是通过表单的标题进行操作。

答案 1 :(得分:2)

更改表单的标题会释放一大堆操作 - 特别是在Vista和Win7下,Aero活动。

快速尝试使用TLabel代替显示进度。像

这样的东西
Label1.caption := IntToStr(i) + '..' + IntTostr(ii); //problemetic line               
Label1.Refresh; // or Repaint

除非您的标签是透明的或在玻璃区域,否则应该做到这一点。

最好遵循Mason Wheeler的建议并使用进度条。由于迭代的总体数为15*TntListBox1.items.Count,因此您可以非常轻松地计算进度值。

答案 2 :(得分:2)

首先:你忘记了tntlistbox3.items.BeginUpdate / tntlistbox3.items.EndUpdate调用(tntlistbox4也一样)。

第二:Why does my program run faster if I click and hold the caption bar?

解决方案(示例):

const
  UpdateInterval = 500; // half a second
var 
  ...
  LastUpdate: Cardinal;
begin   
  ... 
  LastUpdate := GetTickCount + 100000; // forces first update
  For ii := 15 Downto 1 Do //slow change
  Begin
    For I := 0 To TntListBox1.items.Count - 1 Do //very fast change
    Begin     
      if (GetTickCount > (LastUpdate + UpdateInterval)) or
         (GetTickCount < LastUpdate) then
        caption := IntToStr(i) + '..' + IntTostr(ii); //problemetic line               
      ...
    end;
  end;