簡體   English   中英

Delphi使用多線程掃描數據庫目錄

[英]Delphi scanning for database directories using multi threading

我需要掃描驅動器以查找包含我的數據庫文件的目錄,以將它們添加到BDE路徑。 如何使用線程更快地完成代碼? 我正在使用delphi 2007,因此不支持omniThread。 我需要知道如何制作線程以及如何執行它。 這是我的代碼:謝謝。

procedure TMainFrm.RestoreDBDirs;
var
  Lst: TStringList;
  Dirs: string;
  Counter, j, LstFrom, LstTo: integer;
  SearchRec: TSearchRec;
  ST: TScanThread;    
begin
  Screen.Cursor:= crHourGlass;
  try
    try
      ChangeAlias(AliasCombo);//After this procedure the tables are closed
    except
    end;
    Lst:= TStringList.Create;
    Lst.Clear;
    Counter:= 0;

if Assigned(ChooseDrvFrm) then
with ChooseDrvFrm do
begin
  Lst.Add(lvDrives.Selected.Caption);
  Dirs:= lvDrives.Selected.Caption;

  Progress1.Position:= 0;
  Progress1.Visible:= True;
  stBar1.SimpleText:= 'Searching for Databases...';
end
else
begin
  Lst.Add(GetSystemDrive);
  Dirs:= GetSystemDrive;
end;

repeat
  // Update Progress Bar
  if Assigned(ChooseDrvFrm) then
  with ChooseDrvFrm do
  begin
    Progress1.StepBy(1);
    if Progress1.Position = Progress1.Max then
      Progress1.Position:= 0;
  end;

  Dirs:= Lst.Strings[Counter] +'\';
  if (Dirs <> '.') and (Dirs <> '..')then
    if FindFirst(Dirs +'*.*', faDirectory, SearchRec) = 0 then
    begin
      if ((SearchRec.Attr and faDirectory) > 0)
      and (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
      begin
        Lst.Add(Dirs + SearchRec.Name);

        if Assigned(ChooseDrvFrm) then
          ChooseDrvFrm.stBar1.SimpleText:= Dirs + SearchRec.Name;
      end;

      while FindNext(SearchRec) = 0 do
        if ((SearchRec.Attr and faDirectory) > 0) and
            (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
        begin
          Lst.Add(Dirs + SearchRec.Name);
          if Assigned(ChooseDrvFrm) then
            ChooseDrvFrm.stBar1.SimpleText:= Dirs + SearchRec.Name;
        end;
    end;
  Counter:= Counter + 1;
  FindClose(SearchRec);
until Counter = Lst.Count;

Dirs:= '';

if Assigned(ChooseDrvFrm) then
  ChooseDrvFrm.Progress1.Position:= 0;

for Counter:= 0 to Lst.Count - 1 do
begin
  if Assigned(ChooseDrvFrm) then
  with ChooseDrvFrm do
  begin
    Progress1.StepBy(1);
    if Progress1.Position = Progress1.Max then
      Progress1.Position:= 0;
  end;

  if (FileExists(Lst.Strings[Counter] + '\Crt.DB'))
  and (FileExists(Lst.Strings[Counter] + '\Ds.DB'))
  and (FileExists(Lst.Strings[Counter] + '\Turim.DB'))
  and (FileExists(Lst.Strings[Counter] + '\Rprt.DB'))
  and (UpperCase(Lst.Strings[Counter]) <> UpperCase('C:\My Installations\Data'))
  and (UpperCase(Lst.Strings[Counter]) <> UpperCase(ExtractFileDir(ParamStr(0)))) then
  try
    if Assigned(ChooseDrvFrm) then
      ChooseDrvFrm.stBar1.SimpleText:= 'Restoring Databases: '+ Lst.Strings[Counter];

    RestoreAlias(Lst.Strings[Counter]);
  except
    on EDatabaseError do;
  end;
end;

if Assigned(ChooseDrvFrm) then
with ChooseDrvFrm do
begin
  Progress1.Position:= 0;
  Progress1.Visible:= False;
  stBar1.SimpleText:= 'Done';
  MessageDlg('Databases succesfully restored', mtInformation, [mbYes], 0);
  Close;
end;

>     FillAliasCombo;   finally
>     Lst.Free;
>     Screen.Cursor:= crDefault;   end;

對於傳統的旋轉磁盤,穿線不會幫助您。 您的任務是磁盤綁定而不是CPU綁定,線程化將導致磁盤頭移動效率低下。 嘗試使用多個線程執行此操作可能會比單個線程執行的速度慢。

對於固態驅動器或網絡驅動器,您的進程仍受磁盤限制。 但是,使用線程並行執行任務可以減輕磁盤訪問過程的某些延遲,並提高性能。

需要進行一些實驗才能確定如何最好地掃描磁盤,並且可能需要針對不同磁盤類型使用不同的策略。

我認為生產者/消費者方法將是第一件事。 枚舉目錄的生產者線程。 然后,多個使用者讀取這些目錄的內容。 您可能希望將多個目錄批處理到一個任務中,以最大程度地減少線程開銷的影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM