Components and threads question

Hi,

I need to build a Delphi component for my own application that will make recursive search in all hard disk files, so I need to know if it is possible that I build a component which is based on TThread instead of TComponent?

If yes can someone please give me an example of how to define a component which will be based on thread, and if not can someone please tell me the appropriate solution if I want to make the component operations done by a thread.

Thanks in advance for your time
GiantMatrixAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

2266180Commented:
well, a component must be derived from TComponent. that is impossible to leave out (or it will not be a component anymore) but of course, you can define your thread and put a property in your component. something like:

type TMyThread=class(TThread)
       ...
       end;
       
       TMyThreadedComponent=class(TComponent)
       private
         fThread:TMyThread;
         ...
       public
         ...
       end;

of course, if you want to be able to have more operations in the same time, you will have to dynamically create the threads and not having a property anymore (say the user will start searching on drive c, then anotehr search on drive d (and the search on drive c didn't finish) etc. but since we are talking about one harddrive, it might not be a good idea to let the user have this possibility (it will kill the app ;) ). but in otehr circumstances (say download something) this would be an idea ;)

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
alijuniorCommented:
Look this thread code to delete files over directories:

unit uDeleteThread;

interface

uses
  Classes, SysUtils, ComCtrls, Windows, StdCtrls, Dialogs, Forms;

type
  TDeleteThread = class(TThread)
  private
    pRootFolder : String;
    pFileExt : String;
  protected
    procedure Execute; override;
  public
    procedure Terminated( Sender : TObject );
    constructor Create( const vRootFolder, vFileExt: String);
    destructor Destroy; reintroduce;
  end;

implementation

uses uFileWork, uMainDeleteOldFiles;

//uses uCommom, uWait;

{ TDeleteThread }

constructor TDeleteThread.Create( const vRootFolder, vFileExt: String);
begin
  inherited Create(True);

  pRootFolder := IncludeTrailingPathDelimiter( vRootFolder );
  pFileExt := vFileExt;

  OnTerminate := Terminated;

  Main.pThreadsRunning := Main.pThreadsRunning + 1;

  Resume;

end;

destructor TDeleteThread.Destroy;
begin

  inherited Destroy;
end;

procedure TDeleteThread.Execute;
var Rec : TSearchRec;
    Log : TStringList;
    logFile : String;
    subCount,
    delCount,
    errCount,
    falCount : Integer;
begin
  inherited;

//  if DirectoryExists( pRootFolder ) then
//  try
//    DeleteDir( pRootFolder );
//  except
////    on E : Exception do
//      ShowMessage(pRootFolder);
//  end;
//
//  Exit;

  subCount := 0;
  delCount := 0;
  errCount := 0;
  falCount := 0;

  //Busca subdiretórios no diretório raiz
  if FindFirst (pRootFolder + '*.*', faDirectory, Rec) = 0 then
  try
    repeat
      if ((Rec.Attr and faDirectory) = faDirectory) and (Rec.Name<>'.') and (Rec.Name<>'..') then
      begin
        inc( subCount );
        TDeleteThread.Create( pRootFolder + Rec.Name, pFileExt);
      end;
    until FindNext(Rec) <> 0;
  finally
    SysUtils.FindClose(Rec);
  end;

  //exclui os arquivos aqui
  Log := TStringList.Create;
  Log.Add( 'Data de exclusão dos arquivos:' );
  Log.Add( #9 + FormatDateTime( 'dddd, dd/mm/yyyy hh:nn:ss', Now ) );
  Log.Add( 'Diretório base:' );
  Log.Add( #9 + pRootFolder );
  Log.Add( 'Subdiretórios encontrados:' );
  Log.Add( #9 + IntToStr( subCount ) + ' diretório(s)' );
  Log.Add( 'Máscara para exclusão dos arquivos:' );
  Log.Add( #9 + '*' + pFileExt );
  Log.Add( 'Arquivos excluídos:' );

  if FindFirst (pRootFolder + '*' + pFileExt, faAnyFile - faDirectory, Rec) = 0 then
  try
    repeat
      try

        if Windows.DeleteFile( PChar( pRootFolder + Rec.Name ) ) then
        begin
          Log.Add( #9'OK: ' + Rec.Name );
          inc( delCount );
        end
        else
          begin
            Log.Add( #9'FALHA: ' + Rec.Name );
            inc( falCount );
          end;

        Main.UpdateViewMessage( EmptyStr, 'Excluindo gravação das ' + FormatDateTime('hh:nn:ss', GetDateTimeFromFileName( ChangeFileExt( Rec.Name, EmptyStr ) ) ) );

      except
        on E : Exception do
        begin
          inc( errCount );
          Log.Add( 'ERRO: ' + E.Message + ' (' + Rec.Name + ')' );
        end;
      end;

//      S := TStringList.Create;
//      S.Add( 'Diretorio: ' + pRootFolder );
//      S.Add( 'Arquivo: ' + Rec.Name );
//      S.SaveToFile( pRootFolder + Rec.Name + '.txt' );
//      S.Free;

//      Wait( 'Listando ' + Rec.Name );

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

    Log.Add( 'Sumário:' );
    Log.Add( #9 + 'Arquivos excluídos: ' + IntToStr(delCount) );
    Log.Add( #9 + 'Falhas na exclusão: ' + IntToStr(falCount) );
    Log.Add( #9 + 'Erros encontrados : ' + IntToStr(errCount) );

    logFile := IncludeTrailingPathDelimiter( pRootFolder ) + 'DeleteLog.txt';

//    if subCount = 0 then
//      DeleteDir( ExtractFileDir( logFile ) );

    pRootFolder := ExcludeTrailingPathDelimiter( pRootFolder );

    if DirectoryExists( pRootFolder ) then
      if DeleteDir( pRootFolder ) then
        Log.Add( #9 + 'Diretório "' + pRootFolder + '" excluído com sucesso!' )
      else
        Log.Add( #9 + 'Não foi possível excluir o diretório "' + pRootFolder + '".' );

    logFile := ExtractFilePath( pRootFolder ) +
               'DeleteLog' +
               ExtractFileName( pRootFolder ) +
               '.txt';

    Log.SaveToFile( logFile );

    Log.Free;
  end;

end;

procedure TDeleteThread.Terminated(Sender: TObject);
begin

  Main.pThreadsRunning := Main.pThreadsRunning - 1;

end;

end.



You can do like ciuly to create the thread inside the component. Just replace Main.(...) to MyComponent.(...) or Parent.(...) etc.

You can put a limit of threads created at same time to, like:

repeat

  Application.ProcessMessages;

until pThreadsRunning <= 10;

Best regards...
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.