程式介面假死的一種解決方法
阿新 • • 發佈:2019-02-20
當程式介面有進度條或者需要頻繁更新的控制元件時,資料量過大,更新過快,介面就會出現假死。這裡僅僅提供一種解決方案:介面單獨做成,介面的更新和資料的獲取線上程中進行。
開發語言: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;