Avatar billede hestetoften Nybegynder
16. september 2008 - 14:16 Der er 20 kommentarer og
1 løsning

stoppe procedure

Sidder og leger med et pgr der gennemsøger mine drev. dette kan ind imellem godt tage noget tid.

Kan man ikke via et btnClick stoppe en procedure der kører (en proc der tager noget tid at køre)
Avatar billede martinlind Nybegynder
16. september 2008 - 14:20 #1
while BlivVed do
begin

end;
Avatar billede pidgeot Nybegynder
16. september 2008 - 14:27 #2
...og så skal du selvfølgelig også huske at behandle messages mens din handling kører, så den knap rent faktisk registrerer klikket. Hvis du ikke har smidt den handling ud i en separat tråd (det bør du nok), så kræver det en Application.ProcessMessages på et passende tidspunkt.
Avatar billede hrc Mester
16. september 2008 - 14:55 #3
Det smukkeste er at lave søgerutinen som en tråd. Lidt mere besværligt men meget flottere resultat.
Avatar billede coderdk Praktikant
16. september 2008 - 16:19 #4
Enig med hrc, og det er ikke så svært igen, så længe man er opmærksom

http://google.com/search?q=delphi+thread+tutorial
Avatar billede hestetoften Nybegynder
17. september 2008 - 22:01 #5
Jeg er ikke sikker på at jeg forstår.
Eller stiller spm. korrekt.

Jeg her en proc der gennemsøger drev/mapper/undermapper efter filer.
Hvis jeg søger på C: tager søgningen nogle minutter. men hvis jeg kommer i tanke om at jeg vil ændre søgekrit skal søgningen først stoppes.???

Håber dette forklarer hvad jeg vil.!
Avatar billede coderdk Praktikant
17. september 2008 - 22:12 #6
Ja, det kan du med tråde ;)
Avatar billede coderdk Praktikant
17. september 2008 - 22:13 #7
(og med martinlind/pidgeots svar)
Avatar billede borrisholt Novice
19. september 2008 - 09:35 #8
jeg vil da gerne være vært med en findfirst..findnext..findclose lavet i en tråd som du kan stoppe og gøre ved med :

unit ThreadSearch;

interface

uses
  Classes, SysUtils;

type
  TFileFoundEvent = procedure(const FileName: TFileName; const SearchRec: TSearchRec) of object;

  TSerachThread = class(TThread)
  private
    FPath : String;
    FFileMask : TFileName;
    FDirMask : String;
    FAttr : Integer;
    FRecurse : Boolean;
    FWantAllDirs : Boolean;
    FOnFileFound :TFileFoundEvent;
    procedure SetPath(const Value: String);

    Procedure Recurse (const aPath : String); overload;
    Procedure Recurse (const aPath : String; FilesInDir : Integer; Tmp : String; Attr : Integer ); overload;
  protected
    procedure Execute; override;
  public
    Constructor Create;
    Destructor Destroy; override;
    Procedure Start;
    Procedure Stop;
  published
    property Path        : String          read  FPath        write SetPath;
    property FileMask    : TFileName      read  FFileMask    write FFileMask;
    property DirMask    : String          read  FDirMask    write FDirMask;
    property Attr        : Integer        read  FAttr        write FAttr;
    property RecurseDir  : Boolean        read  FRecurse    write FRecurse;
    property WantAllDirs : Boolean        read  FWantAllDirs write FWantAllDirs;
    property OnFileFound : TFileFoundEvent read  FOnFileFound write FOnFileFound;
  end;

implementation

{ TSerachThread }

constructor TSerachThread.Create;
begin
  FileMask        := '*.*';
  DirMask        := '*.*';
  Attr            := faAnyFile;
  RecurseDir      := True;
  FreeOnTerminate := True;
  WantAllDirs    := False;
  Path            := ExtractFilePath(ParamStr(0));
  inherited Create(True);
end;

destructor TSerachThread.Destroy;
begin
inherited Destroy;
end;

procedure TSerachThread.Execute;
begin
  if not Assigned(FOnFileFound) then
    Exception.Create(Self.ClassName + ': No callback procedure defined !!!');

if WantAllDirs then
  Recurse (FPath)
else
  Recurse (FPath, 0, FPath, 0);
end;

procedure TSerachThread.Recurse(const aPath: String; FilesInDir: Integer; Tmp: String; Attr: Integer);
var
  FSearchRec : TSearchRec;
  Res : integer;
begin
  Res := FindFirst (aPath + FFileMask, faAnyFile, FSearchRec);

  while (Res = 0) and (not Terminated) do
  begin
    if (FSearchRec.Name[1] <> '.') and  (FSearchRec.Attr and FAttr > 0 ) then
    begin
      if FSearchRec.Attr and (faAnyFile-faDirectory) <> 0 then
      begin
        inc(FilesInDir);
        if (FilesInDir = 0) then
          FOnFileFound (Tmp, FSearchRec);
      end;

      FOnFileFound (aPath + FSearchRec.Name, FSearchRec);
    end;

    Res := FindNext (FSearchRec);
  end;//while

  FindClose (FSearchRec);

  if (FRecurse) and (not Terminated) then
  begin
    Res := FindFirst (aPath + FDirMask, faAnyFile, FSearchRec);

    while (Res = 0)  and (not Terminated ) do
    begin
      if (FSearchRec.Name[1] <> '.') and (FSearchRec.Attr and faDirectory > 0) then
      begin
        FilesInDir := 0;

        if FSearchRec.Attr and FAttr  <> 0 then
        begin
          Tmp := aPath + FSearchRec.Name+'\';
          Attr := FSearchRec.Attr;
        end;

        Recurse (aPath + FSearchRec.Name+'\', FilesInDir, Tmp, Attr);
      end;

      Res := FindNext (FSearchRec);
    end;

    FindClose (FSearchRec);
  end;
end;

procedure TSerachThread.Recurse(const aPath: String);
var
  FSearchRec : TSearchRec;
  Res : integer;
begin
  Res := FindFirst (aPath +FFileMask, faAnyFile, FSearchRec);

  while (Res = 0) and (not Terminated) do
  begin
    if (FSearchRec.Name[1] <> '.') and  (FSearchRec.Attr and FAttr > 0 ) then
    begin
      if FSearchRec.Attr and (faAnyFile-faDirectory) <> 0 then
        FOnFileFound (aPath + FSearchRec.Name, FSearchRec);
    end;

    Res := FindNext (FSearchRec);
  end;//while

  FindClose (FSearchRec);

  if (FRecurse) and (not Terminated ) then
  begin
    Res := FindFirst (aPath + FDirMask, faAnyFile, FSearchRec);

    while (Res = 0)  and (not Terminated ) do
    begin
      if (FSearchRec.Name[1] <> '.') and (FSearchRec.Attr and faDirectory <> 0) then
      begin
        if FSearchRec.Attr and FAttr  <> 0 then
          FOnFileFound (aPath + FSearchRec.Name, FSearchRec);

        Recurse (aPath + FSearchRec.Name+'\');
      end;//if

      Res := FindNext (FSearchRec);
    end;//while
    FindClose (FSearchRec);
  end;//if
end;

procedure TSerachThread.SetPath(const Value: String);
begin
  FPath := IncludeTrailingBackslash(Value);
end;

procedure TSerachThread.Start;
begin
  Resume;
end;

procedure TSerachThread.Stop;
begin
  Terminate;
end;

end.

Jens B
Avatar billede hrc Mester
19. september 2008 - 09:57 #9
borrisholt: Jeg har haft store problemer med at få resume til at virke. Bruger jeg Suspended := false virker det fint. Har du testet ovenstående?

Desuden burde IncludeTrailingBackslash erstattes med IncludeTrailingPathDelimiter og indføjes i kaldet til Recurse - sådan bare for konsekvensens skyld. Ellers ligner det noget jeg kunne have lavet :-)
Avatar billede borrisholt Novice
19. september 2008 - 12:13 #10
Ja ovenstående er meget testet .. Dog tror jeg aldrig jeg har brugt resume ... kun terminate
Avatar billede hestetoften Nybegynder
22. september 2008 - 12:49 #11
Ok jeg er sq ikke haj nok til lige at gennemskue dette

Som jeg kan se skal unitten ThreadSearch køre ved siden af min form/unit og kaldes derfra.

men jeg kan ikke lige se hvordan jeg kalder dens procedurer (søg, start, stop)

Desværre behøver jeg lidt mere hjælp.

MVH Lars
Avatar billede borrisholt Novice
22. september 2008 - 12:58 #12
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ThreadSearch, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    Search: TSerachThread;
  public
    procedure OnSearchFileFound(const FileName: TFileName; const SearchRec: TSearchRec);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Search.Suspended then
    Button1.Caption := 'Pause'
  else
    Button1.Caption := 'Start';

  Search.Suspended := not Search.Suspended;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Search := TSerachThread.Create;
  Search.Path := 'C:\';
  Search.OnFileFound := OnSearchFileFound;
end;

procedure TForm1.OnSearchFileFound(const FileName: TFileName; const SearchRec: TSearchRec);
begin
  Memo1.Lines.Add(FileName)
end;

end.

Sånt :D
Avatar billede hestetoften Nybegynder
24. september 2008 - 12:54 #13
Den stopper godtnok, men den fortsætter med de samme kriterier.

Det jeg har behov for er at stoppe og indsætte nye kriterier(søgemappe/drev) og derefter starte forfra med nye krit
Avatar billede borrisholt Novice
24. september 2008 - 13:15 #14
Nååe så skal du terminere tråden ikke pause den ... Så skal du bare sætte den op igen
Avatar billede hestetoften Nybegynder
24. september 2008 - 13:17 #15
sætte den op igen?
Avatar billede michael-schou Novice
24. september 2008 - 18:12 #16
hestetoften : jeg har fået følgende til at virke ud fra borrisholt's kode :

Indsæt en knap mere på din form og kald den for Stop eller Terminate.

Jeg har Lavet en PROCEDURE det hedder StartAgain - Som bliver kaldt i FormCreate og
Button2 PROCEDURE'ne

----------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ThreadSearch, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    Search: TSerachThread;
  public
    { Public declarations }
    procedure OnSearchFileFound(const FileName: TFileName; const SearchRec: TSearchRec);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Procedure StartAgain;
begin
Form1.Search := TSerachThread.Create;
Form1.Search.Path := 'C:\';
Form1.Search.OnFileFound := Form1.OnSearchFileFound;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
StartAgain;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
If Search.suspended Then

  Form1.Button1.Caption := 'Start'
else
  Form1.Button1.Caption := 'Pause';

Search.suspended := not Search.suspended;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Search.Terminate;
Form1.Button1.Caption := 'Start';
showMessage('Process Stopped');
StartAgain;
end;

procedure TForm1.OnSearchFileFound(const FileName: TFileName; const SearchRec: TSearchRec);
begin
Memo1.Lines.Add(FileName);
end;

end.

----------------------------------------------------------------

borrisholt tror faktisk jeg har forstået det der med Thread, skal dog lige lege lidt mere med det :D

//Michael.
Avatar billede michael-schou Novice
24. september 2008 - 21:47 #17
UPS - Lille rettelse :

procedure TForm1.Button1Click(Sender: TObject);
begin
If Search.suspended Then

  Form1.Button1.Caption := 'Start'
else
  Form1.Button1.Caption := 'Pause';

Search.suspended := not Search.suspended;
end;

Skal laves til (Om bytning på start og pause):

procedure TForm1.Button1Click(Sender: TObject);
begin
If Search.suspended Then

  Form1.Button1.Caption := 'Pause'
else
  Form1.Button1.Caption := 'Start';

Search.suspended := not Search.suspended;
end;

Sådan :-)
Avatar billede hestetoften Nybegynder
01. oktober 2008 - 12:11 #18
Leger lige lidt med det

Mange tak for hjælpen

Læg et svar
Avatar billede michael-schou Novice
01. oktober 2008 - 15:05 #19
Jeg syntes det er mest fair hvis det er

borrisholt det får points. :-)

//Michael.
Avatar billede borrisholt Novice
01. oktober 2008 - 15:12 #20
Fint nok jeg trænger også så voldsomt ;o)

Jens Borrisholt
Avatar billede michael-schou Novice
02. oktober 2008 - 08:10 #21
Jeg det var nemlig det jeg tænkte :D

//Michael.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester