AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Schlafende Threads

Ein Thema von shmia · begonnen am 11. Mai 2012 · letzter Beitrag vom 15. Mai 2012
 
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#8

AW: Schlafende Threads

  Alt 11. Mai 2012, 20:24
Irgendwie gefällt mir das auch alles nicht, wieso z.b. das ResetEvent vor DoWork? Ausserdem wird as FEvent zu spaet erzeugt.

wie wärs mit:

Delphi-Quellcode:

type
  TSleepingThread = class(TThread)
  protected
    FEvent: TEvent;
    FBusy: Boolean;
    procedure Execute; override;
    procedure DoWork; virtual; abstract;
  public
    function WakeUp: Boolean;
    constructor Create(_Suspended: Boolean);
    destructor Destroy; override;
    property Busy: Boolean read FBusy;
  end;

  TTestThread = class(TSleepingThread)
  private
    FCountLoop: Integer;
  protected
    procedure DoWork; override;
    property CountLoop: Integer read FCountLoop;
  end;

{ TMyThread }

constructor TSleepingThread.Create(_Suspended: Boolean);
begin
  FEvent := TEvent.Create(nil, True, False, '');
  FBusy := False;
  inherited Create(_Suspended);
end;

destructor TSleepingThread.Destroy;
begin
  Terminate; // FTerminate setzen
  WakeUp; // Event setzen
  WaitFor; // warten bis der eigene Thered sich beendet hat
  FreeAndNil(FEvent);
  inherited;
end;

function TSleepingThread.WakeUp: Boolean;
begin
  Result := FBusy;
  if not Result then
    FEvent.SetEvent;
end;

procedure TSleepingThread.Execute;
begin
  while not Terminated do begin
    case FEvent.WaitFor(INFINITE) of
      wrSignaled: begin
          if not Terminated then begin
            FBusy := True;
            DoWork;
            FEvent.ResetEvent;
            FBusy := False;
          end;
        end;
      wrTimeout: ;

      wrError: begin
          ReturnValue := FEvent.LastError;
          Exit;
        end;

      wrAbandoned:
        Exit;
    end;
  end;
end;

{ TTestThread }

procedure TTestThread.DoWork;
var
  t: Cardinal;
begin
  t := GetTickCount;
  while GetTickCount - t < 2000 do
    Sleep(100);
  Inc(FCountLoop);
end;

procedure TForm28.OnTerminateThread(_Sender: Tobject);
begin
  caption := inttostr((_Sender as TTestThread).CountLoop);
end;

procedure TForm28.Button1Click(Sender: TObject);

var
  tt: TTestThread;
begin
// recht sinnloses beispiel da FreeAndNil immer auf Ende wartet aller arbeiten wartet
// und es somit "blockierend" aussieht
  tt := TTestThread.Create(False);
  try
    tt.OnTerminate := OnTerminateThread;
    if tt.WakeUp then begin
      // joa konnte ausgefuerht werden
    end;
    Sleep(10); // naja irgendwas im HauptThread zwischendurch
  finally
    FreeAndNil(tt);
  end;
end;
Edit: Ah Thread falsch aufgeweckt ;P
Edit2: Beispiel erweiter (u.a. busy usw.)

Geändert von brechi (11. Mai 2012 um 20:40 Uhr) Grund: erweitert
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:09 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz