Multithreading delphi文件搜索多线程

Multithreading delphi文件搜索多线程,multithreading,delphi,Multithreading,Delphi,如果我这样执行,我的应用程序在找到所有文件并将它们发送到列表框之前不会响应 我的问题是如何使这个函数多层次化,以避免出现无响应的情况!我仍然是一颗冰 procedure TfrMain.FileSearch(const PathName, FileName : string; txtToSearch : string; const InDir : boolean); var Rec : TSearchRec; Path : string; txt : string;

如果我这样执行,我的应用程序在找到所有文件并将它们发送到列表框之前不会响应 我的问题是如何使这个函数多层次化,以避免出现无响应的情况!我仍然是一颗冰

procedure TfrMain.FileSearch(const PathName, FileName : string; txtToSearch : string; const InDir : boolean);
var Rec  : TSearchRec;
    Path : string;
    txt  : string;
    fh   : TextFile;
    i    : integer;
begin


Path := IncludeTrailingBackslash(PathName);
if FindFirst(Path + FileName, faAnyFile - faDirectory, Rec) = 0 then
 try
   repeat

     AssignFile(fh, Path + Rec.Name);
     Reset(fh);
     Readln(fh,txt);

     if ContainsStr(txt, txtToSearch) then
        ListBox1.Items.Add(Path + Rec.Name);

   until FindNext(Rec) <> 0;
 finally
   FindClose(Rec);

 end;

If not InDir then Exit;

if FindFirst(Path + '*.*', faDirectory, Rec) = 0 then
 try
   repeat
    if ((Rec.Attr and faDirectory) <> 0)  and (Rec.Name<>'.') and (Rec.Name<>'..') then
     FileSearch(Path + Rec.Name, FileName, txtToSearch, True);
   until FindNext(Rec) <> 0;
 finally
   FindClose(Rec);
 end;
end;
procedure TfrMain.FileSearch(常量路径名,文件名:string;txtToSearch:string;常量InDir:boolean);
var Rec:TSearchRec;
路径:字符串;
txt:字符串;
fh:TextFile;
i:整数;
开始
路径:=includeTrailingBackslax(路径名);
如果FindFirst(路径+文件名,faAnyFile-faDirectory,Rec)=0,则
尝试
重复
AssignFile(fh,Path+Rec.Name);
复位(fh);
Readln(fh,txt);
如果包含sstr(txt,txtToSearch),则
ListBox1.Items.Add(Path+Rec.Name);
直到FindNext(Rec)0;
最后
FindClose(Rec);
结束;
如果没有InDir,则退出;
如果FindFirst(路径+'*.*',faDirectory,Rec)=0,则
尝试
重复
如果((Rec.Attr和faDirectory)0)和(Rec.Name'.'和(Rec.Name'.'),则
FileSearch(路径+记录名,文件名,txtToSearch,True);
直到FindNext(Rec)0;
最后
FindClose(Rec);
结束;
结束;

您可以找到一篇关于使用实现的后台文件扫描程序的文章。

您可以将文件扫描内容放入一个线程中,然后在完成工作后将windows消息发送到主窗体,主窗体随后更新列表框(未测试代码,将其作为伪代码):

您可以这样使用它:

Thead := TFileSearchThread.Create (Path);
Thread.Start;
type
  TMainForm = class(TForm)
    ListBox1: TListBox;
  private
    procedure WMFileSearchFinished (var Msg : TMessage); message WM_FILESEARCH_FINISHED;
  public
    { Public declarations }
  end;

implementation

procedure TMainForm.WMFileSearchFinished (var Msg : TMessage);
begin
  ListBox1.Items.AddStrings (Thread.FileNames);
end;
主窗体将有如下消息处理程序:

Thead := TFileSearchThread.Create (Path);
Thread.Start;
type
  TMainForm = class(TForm)
    ListBox1: TListBox;
  private
    procedure WMFileSearchFinished (var Msg : TMessage); message WM_FILESEARCH_FINISHED;
  public
    { Public declarations }
  end;

implementation

procedure TMainForm.WMFileSearchFinished (var Msg : TMessage);
begin
  ListBox1.Items.AddStrings (Thread.FileNames);
end;

PostMessage(MainForm.Handle,WM_FILESEARCH_FINISHED,0,0)不应该出现错误
可与
Synchronize
?@kobik一起使用,无需担心,
Handle
属性是只读的,其读取是原子的。而且它必须不同于0(控件将是死的,无法接收任何消息),因此getter永远不会
CreateHandle
句柄为0时它会做什么。风险在于对象实例本身,如果您破坏
MainForm
并尝试访问它,您将像往常一样获得AV。而且,Emba也是:-)@kobik
Synchronize
在内部使用
SendMessage
,这是与
PostMessage