我需要扫描驱动器中包含数据库文件的目录,将它们添加到BDE路径中。如何使用线程使代码更快地执行?我使用的是Delphi2007,所以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 InstallationsData'))
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绑定的,线程化会导致磁盘头移动效率低下。尝试使用多个线程执行此操作可能会比使用单个线程慢。
对于固态驱动器或网络驱动器,则您的进程仍然是磁盘绑定的。但是,使用线程并行执行任务可以减轻磁盘访问进程的一些延迟,并提高性能。
需要一些实验来找出如何最好地扫描磁盘,并且可能需要针对不同的磁盘类型使用不同的策略。
我认为首先要尝试的是生产者/消费者的方法。枚举目录的生产者线程。然后多个消费者读取这些目录的内容。您可能希望将多个目录批处理到一个任务中,以最大限度地减少线程开销的影响。