1. 程式人生 > >程式介面假死的一種解決方法

程式介面假死的一種解決方法

當程式介面有進度條或者需要頻繁更新的控制元件時,資料量過大,更新過快,介面就會出現假死。這裡僅僅提供一種解決方案:介面單獨做成,介面的更新和資料的獲取線上程中進行。

開發語言: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;