当程序界面有进度条或者需要频繁更新的控件时,数据量过大,更新过快,界面就会出现假死。这里仅仅提供一种解决方案:界面单独做成,界面的更新和数据的获取在线程中进行。
开发语言:Delphi
程序界面:
1.获取源文件夹的文件个数的同时更新项目个数
2.文件获取完毕后把文件从源文件夹拷贝到目标文件夹,同时更新进度条。
程序实例:(改进前,界面假死)
//数据页面显示的同时,更新拷贝
procedure TFrmLNBStatus.FormShow(Sender: TObject);
begin
sSrcDir :=Copy( FrmLNBStatus.sSrcDir, 0, length(FrmLNBStatus.sSrcDir) );
sDstDir :=Copy( FrmLNBStatus.sDstDir, 0, length(FrmLNBStatus.sDstDir) );
//数据获取
sFilelst := TStringList.Create;
if( FindFirst(sSrcDir+'\*.SIR',faDirectory,SearchRec) = 0) then //*.SIR
begin
repeat
sFilelst.Add(SearchRec.Name);
msg := IntToStr(sFilelst.Count);
UpdateLabel;
until (FindNext(SearchRec) <> 0);
end;
FindClose(SearchRec);
//数据复制
for i := 0 to sFilelst.Count - 1 do
begin
CopyFile(PWideChar(WideString(sSrcDir+ '\'+sFilelst[i])),PWideChar(WideString(sDstDir+ '\'+sFilelst[i])),True);
pos :=Trunc((i/sFilelst.Count)*100);
if pos > 100 then pos := 99;
Progress;
end;
pos := 100;
Progress;
end;
//数据获取页面:项目个数更新
procedure TFrmLNBStatus.UpdateLabel;
begin
FrmLNBStatus.Label3.Caption := msg;
FrmLNBStatus.Label3.Refresh;
end;
//数据获取页面:进度条更新
procedure TFrmLNBStatus.Progress;
begin
FrmLNBStatus.ProgressBar1.Position := pos;
FrmLNBStatus.ProgressBar1.Refresh;
end;
程序实例:(改进后,界面流畅,速度变快)
//线程要引入 ActiveX
//定义部分
TGetDataThread = class(TThread)
private
pos : Integer;
msg : String;
procedure GetDataExec;
procedure Progress;
procedure UpdateLabel;
procedure ShowStatus;
procedure CloseStatus;
protected
procedure Execute; override;
public
constructor Create();
end;
//实现部分
//线程新规
constructor TGetDataThread.Create;
begin
inherited Create(False);
FreeOnTerminate := True;
end;
//线程执行
procedure TGetDataThread.Execute;
begin
CoInitialize(nil);
GetDataExec;
CoUninitialize();
end;
//数据获取页面:进度条更新
procedure TGetDataThread.Progress;
begin
FrmLNBStatus.ProgressBar1.Position := pos;
FrmLNBStatus.ProgressBar1.Refresh;
end;
//数据获取页面:显示
procedure TGetDataThread.ShowStatus;
begin
FrmLNBStatus.Show;
end;
//数据获取页面:关闭
procedure TGetDataThread.CloseStatus;
begin
FrmLNBStatus.Close;
end;
//数据获取页面:项目个数更新
procedure TGetDataThread.UpdateLabel;
begin
FrmLNBStatus.Label3.Caption := msg;
FrmLNBStatus.Label3.Refresh;
end;
//获取获取
procedure TGetDataThread.GetDataExec;
var
sSrcDir ,sDstDir : String;
SearchRec:TSearchRec;
sFilelst :TStringList;
i : Integer;
begin
Synchronize(ShowStatus);
sSrcDir :=Copy( FrmLNBStatus.sSrcDir, 0, length(FrmLNBStatus.sSrcDir) );
sDstDir :=Copy( FrmLNBStatus.sDstDir, 0, length(FrmLNBStatus.sDstDir) );
//数据获取
sFilelst := TStringList.Create;
if( FindFirst(sSrcDir+'\*.SIR',faDirectory,SearchRec) = 0) then //*.SIR
begin
repeat
sFilelst.Add(SearchRec.Name);
msg := IntToStr(sFilelst.Count);
Synchronize(UpdateLabel);
until (FindNext(SearchRec) <> 0);
end;
FindClose(SearchRec);
//数据复制
for i := 0 to sFilelst.Count - 1 do
begin
CopyFile(PWideChar(WideString(sSrcDir+ '\'+sFilelst[i])),PWideChar(WideString(sDstDir+ '\'+sFilelst[i])),True);
pos :=Trunc((i/sFilelst.Count)*100);
if pos > 100 then pos := 99;
Synchronize(Progress);
end;
pos := 100;
Synchronize(Progress);
Synchronize(CloseStatus);
end;
//点击按钮时,数据获取页面显示
procedure TfrmViewerSP.fraViewerFoot1btRenewClick(Sender: TObject);
begin
FrmLNBStatus.sSrcDir := Copy(sSrcDir,0,length(sSrcDir));
FrmLNBStatus.sDstDir := Copy(sDstDir,0,length(sDstDir));
FrmLNBStatus.ShowModal;
end;
//数据页面显示的同时,线程调用
procedure TFrmLNBStatus.FormShow(Sender: TObject);
begin
TGetDataThread.Create;
end;