程序界面假死的一种解决方法 - 线程


当程序界面有进度条或者需要频繁更新的控件时,数据量过大,更新过快,界面就会出现假死。这里仅仅提供一种解决方案:界面单独做成,界面的更新和数据的获取在线程中进行。

开发语言: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;




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值