0

BDE 경로에 데이터베이스 파일을 추가하기 위해 데이터베이스 파일이있는 디렉토리의 드라이브를 스캔해야합니다. 스레드를 사용하여 코드를 더 빨리 수행하려면 어떻게해야합니까? delphi 2007을 사용 중이므로 omniThread가 지원되지 않습니다. 스레드를 만드는 방법과 스레드를 실행하는 방법을 알아야합니다. 이것은 내 코드입니다. 감사합니다.다중 스레드를 사용하여 데이터베이스 디렉토리를 검색하는 Delphi

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; 
+0

아마도 이것은 끔찍한 생각입니다. 스레딩 때문이 아니라 인덱싱되지 않은 네트워크 리소스에 막대한 양의 구문 분석이 포함되기 때문입니다. 스레딩을 사용하더라도 모든 스레드가 완료 될 때까지 기다려야하며 네트워크 드라이브에 액세스하는 시간 초과는 몇 분을 초과 할 수 있습니다. – mg30rg

+0

[앞 페이지] (http://otl.17slon.com/)에는 D2007이 지원됩니다. –

답변

3

전통적인 회전 디스크의 경우 스레딩이 도움이되지 않습니다. 귀하의 작업은 CPU 바운드가 아닌 디스크 바운드이며 스레딩은 비효율적 인 디스크 헤드 이동을 유발합니다. 여러 스레드에서이 작업을 시도하면 단일 스레드보다 속도가 느려질 수 있습니다.

솔리드 스테이트 드라이브 또는 네트워크 드라이브의 경우 프로세스는 여전히 디스크 바인딩 상태입니다. 그러나 스레드를 사용하여 병렬로 작업을 수행하면 디스크 액세스 프로세스의 대기 시간이 완화되고 성능이 향상 될 수 있습니다.

디스크를 가장 잘 검사하는 방법을 알아 내려고 약간의 실험이 필요하며 다른 디스크 유형에 대해 다른 전략이 필요할 수 있습니다.

나는 프로듀서/소비자 접근법이 가장 먼저 시도 할 것이라고 생각합니다. 디렉터리를 열거하는 제작자 스레드입니다. 그런 다음 여러 소비자가 해당 디렉토리의 내용을 읽습니다. 스레딩 오버 헤드의 영향을 최소화하기 위해 여러 디렉토리를 단일 태스크로 배치해야 할 수 있습니다.

+0

감사합니다. 아마도 파일 시스템이 색인이되거나 내가 모르는 어떤 것 때문에 가능할 수도 있습니다 ... 다른 방법으로 perhapse가 있습니까? – user1349751

+0

이것을 확인하려고 할 수 있습니다. http://stackoverflow.com/questions/3153428/windows-search-4-query-delphi-example 색인 생성은 플랫폼에 따라 다릅니다 (W7 이전에는 다른 API)로 전환 할 수 있습니다. –

+0

인덱스 서비스를 사용하는 것이 옵션 일 수 있습니다. 목표물이 색인되는 한. –