【问题标题】:Delphi - threads and FindFirst functionDelphi - 线程和 FindFirst 函数
【发布时间】:2010-06-18 15:53:44
【问题描述】:

当我尝试在线程中创建递归搜索函数(使用 delphi 7)时遇到了一个大问题,代码如下:

TParcFicDir = class(TThread)
private
 several variables..
 protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: Boolean);


constructor TParcFicDir.Create(CreateSuspended: Boolean);
begin
 inherited Create(CreateSuspended);
end;

procedure TParcFicDir.Execute;
begin
 try
  FindFiles(FStartDir,FMask);//'c:\' and '*.*'
 except on e:Exception do
 end;
end;

procedure TParcFicDir.FindFiles(StartDir, FileMask: string);
var
  wTmp              : string;
  f:TextFile;
  wTempSR:TSearchRec;

  function Search(StartDir, FileMask: string): string;
  var
    SR              : TSearchRec;
    IsFound         : Boolean;
    files           : integer;
    dirs            : integer;
    t               : string;
  begin
    try
      files := 0;
      dirs := 0;
      if StartDir[length(StartDir)] <> '\' then
        StartDir := StartDir + '\';
      try
        IsFound := (FindFirst(StartDir + '*.*', faAnyFile, SR) = 0);// here the thread gets interrupted
      except on e: Exception do
      end;
      while IsFound do
      begin
        if (SR.Name <> '.') and (SR.Name <> '..') then
          if ((SR.Attr and faDirectory) <> 0) then
          if FScanDirs then 
          begin
            inc(dirs);
            t := Search(StartDir + SR.Name, FileMask);
            try
              files := files + strtoint(copy((t), 0, pos('#', t) - 1));//old code, don't take on calcul;
              Delete(t, 1, pos('#', t));
              dirs := dirs + strtoint(t);
            except on e: Exception do
            end;
            begin
              t := StartDir + SR.Name;
              wTmp := t;
              wtmp := '';
              Inc(FDirNo);
              writeln(f,t);
              inc(filno);
            end;
          end
          else
          if ScanFiles then 
          begin
           inc(filno);
           inc(files);
          end;
        IsFound := FindNext(SR) = 0;
      end;
      Result := IntToStr(files) + '#' + IntToStr(dirs);
      sysutils.FindClose(SR);
    except on e: Exception do
    end;
  end;
begin
 filno := 0;
  try
    try
      if trim(FPathFileTmp)<>'' then
       AssignFile(f, FPathFileTmp+'Temp.bak')
      else
       AssignFile(f,ExtractFileDir(GetDllName)+'\Temp.bak');
      Rewrite(f);
      Search(StartDir, FileMask);
      if StartDir[length(StartDir)] = '\' then
        delete(StartDir, length(StartDir), 1);
      wTmp := StartDir;
      wTmp := '';
      if FindFirst(StartDir, faDirectory, wTempSR) = 0 then
      writeln(f);
      writeln(f);
      CloseFile(f);
    except on e: Exception do
    end;
  finally
  end;
end;

好的,可能代码有点乱,但我不明白为什么线程在'findfirst'部分结束......我用谷歌搜索了它,没有结果。

任何帮助将不胜感激!

提前致谢

【问题讨论】:

  • 在您的异常处理程序中添加一个 ShowMessage(E.Message),当引发异常时,至少您有一些关于它的信息。
  • 是的。 try..except on Exception do end; 是个非常糟糕的主意。
  • 线程真的与这个问题相关吗?如果您在程序中单独运行此代码会怎样?你说代码乱七八糟,所以先担心这个,然后然后担心让它在单独的线程中工作。
  • 好吧,我猜你忘了告诉我们这有什么问题?抱歉,但我们不介意编译并尝试找出问题所在。
  • 如果代码因为不好看而“乱七八糟”,那么请花 2 分钟时间让它看起来不错。尽可能多地消除阻碍人们帮助您的障碍。丑陋的代码是一个分散注意力的障碍。无关的细节也是如此。一个可能不相关的细节是这是在一个单独的线程中。您不必怀疑它是否与线程相关。在你的主线程中测试它并找出答案。更好的是,在一个只运行这段代码的新程序中运行它。当你说某事“不起作用”时,你必须更加具体。不要让人猜测;这是另一个障碍。

标签: delphi search file multithreading


【解决方案1】:

在您发布的代码中,我看到您 try catch and forget 异常。当您破坏了包含类似内容的代码时,我要做的第一件事就是删除空的 except 块。很可能他们不知道发生了什么,因为你把需要的信息扔掉了。

您的代码中有两次对FindFirst() 的调用。您尝试查找目录的那个的用法是可疑的。我会把你的代码改成这样的。

var
 SR : TSearchRec;

begin
  if FindFirst('C:\',faDirectory,SR) <> 0 then
     RaiseLastOSError;
end;

然后你会看到FindFirst()失败的原因。

在您查找目录的情况下,我不使用FindFirst(),而是使用DirectoryExists() 调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多