设置一个起始时间dtStart,每循环一次记录时间dtNow,同时取得执行一次需要的时间fTime,用fTime*循环次数,就可以得到总时间。
如
var dtStart,dtNow: TDateTime;
fTime,AllTime,fRest: Float;
iMin,iSec: Integer;
ii: Integer;
FirstLoop: Boolean;
begin
dtStart := Now;
FirstLoop := True;
for ii := 0 to 10000 do
begin
Application.ProcessMessage;
//本次循环结束
dtNow := Now;
if FirstLoop then
begin
fTime := Now - dtStart;
AllTime := fTime * 10000; //总时间
FirstLoop := False;
end;
fTime := dtNow - dtStart;
fRest := AllTime - fTime;
//自己取转换为分钟和秒吧
end;
end;
如
var dtStart,dtNow: TDateTime;
fTime,AllTime,fRest: Float;
iMin,iSec: Integer;
ii: Integer;
FirstLoop: Boolean;
begin
dtStart := Now;
FirstLoop := True;
for ii := 0 to 10000 do
begin
Application.ProcessMessage;
//本次循环结束
dtNow := Now;
if FirstLoop then
begin
fTime := Now - dtStart;
AllTime := fTime * 10000; //总时间
FirstLoop := False;
end;
fTime := dtNow - dtStart;
fRest := AllTime - fTime;
//自己取转换为分钟和秒吧
end;
end;
解决方案 »
- 读其他进程的堆栈数据
- 如何从库中读写图片在DELPHI下
- 为什么超级终端接受进来的条形码值是乱码呢? 请教高手!高分相送!
- 问几个关于qreport的问题
- 真奇怪啊?
- 100分的问题:如何实现在DBGrid中实现回车后光标移到本行下一列字段中,若本行结束则移到下一行第一列字段。(UP有分)
- 怎么实现汉化软件?急,急急!!
- 如何获得“我的电脑”,“回收站”等图标的文件名?就像Magic Set一样
- 兄弟们,救救我吧,我非得吧硬盘里得程序给弄出来!
- 求助,急急急!!!
- 高分请教,如何用Delphi实现Active Documents,只要对我有帮助,都有分。
- undeclared identitier:'showmessage'是什么意思?为什么showmessage('显示对话框')这语句运行不了?
段代码只会执行一次,又怎么能实时知道逝去时间,”自己取转换为分钟和秒吧”,怎么取?我不会,希望朋友们能给出具体的代码,不要只说想法好吗?
Totals,Remains: String;
begin
Totals := '大约需1小时';
Remains := '还剩1小时';
Total := 3600000;
Remain := 3600000;
Passing := 0;
Starting := GetTickCount;
For I:=1 to Count do
begin
{Here do your processing}
Ending := GetTickCount;
Interval := Ending - Starting;
Inc(Passing,Interval); Total := Count * Interval;
Application.ProcessMessages;
Remain := Total - Passing;
Totals := Format('大约需%d分%d秒',[Total div 60000,(Total mod 60000) div 1000]);
Remains := Format('还剩%d分%d秒',[Remain div 60000,(Remain mod 60000) div 1000]);
end;
end;
Inc(Passing,Interval);
肯定不对,这样是把所有循环中的时刻与开始的时刻差累加,而实际上,只有当前的GetTickCount才是逝去时间。所以Totals和Remains不对。
var Starting,Ending,Interval,Total,Remain, Passing,I: Cardinal;
Totals,Remains: String;
begin
//Count := 10000;
Totals := '大约需1小时';
Remains := '还剩1小时';
Total := 3600000;
Remain := 3600000;
Passing := 0;
Starting := GetTickCount;
For I:=1 to Count do
begin
{Here do your processing} Ending := GetTickCount;
Interval := Ending - Starting;
Inc(Passing,Interval); Total := Count * Interval;
Remain := Total - Passing;
Totals := Format('大约需%d分%d秒',[Total div 60000,(Total mod 60000) div 1000]);
Remains := Format('还剩%d分%d秒',[Remain div 60000,(Remain mod 60000) div 1000]); Application.ProcessMessages; Starting := Ending;
end;
end;
Remains := '还剩1小时';
是预估的,但我不喜欢这样限死了,程序一开始运行时的显示问题很让我头痛。
//Remains := '还剩1小时';
去掉就是了啊!只要进入循环,执行一条你的操作,就可以显示比较正确的提示了。
在这之前,你可以干点别的,吸引用户的注意力!变魔术吧!
因为是估计的时间,Windows也是,我们可以这样,要完全精确是不可能得:
EsTime:=0;for i:=0 to 1000 do
begin
ALoopTimeStart:=Gettickcount
////Loop
...
ALoopTimeEnd:=GettickCount;
EsTime:=EsTime+ALoopTimeStart-ALoopTimeEnd;
AvgTime:= (AvgTime*(i-1) + (ALoopTimeStart-ALoopTimeEnd)) / i
msg1:=Format('Total Time:%d',[AvgTime*1000]);
msg2:=format('Es time:%d',[EsTime]);
end;
至于时间的转化,可以参考楼上的。
…………………………………………
有一大车啊!
……
procedure DoingIt(Count: Carinal);
var
Starting,Ending,Interval,Total,Remain, Passing,I:Cardinal; Totals,Remains: String;
begin //Count := 10000;
Totals := '大约需1小时';
Remains := '还剩1小时';
Total := 3600000;
Remain := 3600000;
Passing := 0;
Starting := GetTickCount;
For I:=1 to Count do begin {Here do your processing}
Ending := GetTickCount; Interval := Ending - Starting; Inc(Passing,Interval); Total := Count * Interval; Remain := Total - Passing; Totals := Format('大约需%d分%d秒',[Total div 60000,(Total mod 60000) div 1000]); Remains := Format('还剩%d分%d秒',[Remain div 60000,(Remain mod 60000) div 1000]); Application.ProcessMessages; Starting := Ending; end; end; //不过,肯定不会这是样的:)不会有人用这样的
方法有,但如果用自己的算法就是有点效果不是很好,你不如直接用WINAPI;
事情应该基于估计和统计:最开始时(循环开始前)没有人能知道需要多少时间能完成,所以在完成第一个循环前,只能是不显示或显示一个估计数“大约一小时或小于一小时”;
在完成第一个循环后,或者在N个循环后总算是过了1ms,那么就可以依据以前的数据来统计时间总数及剩余时间,即 所用时间数÷已经循环数 为目前所知的平均数,当然这个数应该在分子和分母都不为零的情况下才能开始计算,设这个数为k。那么,时间总数 = 总循环数×k = 总循环数×所用时间数÷已经循环数
剩余时间数 = (总循环数-已经循环数)×k = (总循环数-已经循环数)×所用时间数÷已经循环数当然,每过一个循环都要重新计算一下k,就象Windows的复制或IE的下载进度时间一样,其速度不是均速的,甚至出现估计时间增多的情况。剩下的一个问题就是时间显示的技巧了,这个应该比较好办,拆成分和秒,如果分为0则不显示。其实了解算法就已经编码了,但你非要,那就给出伪代码吧:var
i: Integer;
dwBegin: LongWord; // 开始的系统时间
dwNow: LongWord; // 每次取系统时间
begin
设置总时间和剩余时间为空或“1小时”; dwBegin := GetTickCount; // 以毫秒为单位
for i:=1 to 循环总数 do
begin
你的代码;
dwNow := GetTickCount;
if dwNow>dwBegin then
begin
显示总时间( 循环总数*(dwNow-dwBegin) div i div 1000 );
显示剩余时间( (循环总数-i)*(dwNow-dwBegin) div i div 1000 );
end;
end;
end;>Kingron(对CSDN愤怒中……)
老兄出了什么事?为何愤怒?