I've discovered some new handy classes in XE2 and I said to myself why not implement them into prior versions via my own class?
TCountdownEventEx = class
private
FCurrent,
FInitial: integer;
FEvent: TEventEx;
public
constructor Create(aSize: integer);
destructor Destroy; override;
procedure Add(aSize: integer);
function IsFinish: boolean;
procedure Reset;
procedure Signal;
procedure Wait(aTimeout: cardinal);
property Current: integer read FCurrent;
property Initial: integer read FInitial;
end;
{ TCountdownEventEx }
procedure TCountdownEventEx.Add(aSize: integer);
begin
if IsFinish then
raise Exception.Create('Already signalled');
TInterlockedEx.Add(FCurrent, aSize);
end;
constructor TCountdownEventEx.Create(aSize: integer);
begin
FInitial := aSize;
FEvent := TEventEx.Create;
Reset;
end;
destructor TCountdownEventEx.Destroy;
begin
FEvent.Free;
inherited;
end;
procedure TCountdownEventEx.Reset;
begin
FEvent.Reset;
FCurrent := FInitial;
end;
procedure TCountdownEventEx.Signal;
begin
TInterlockedEx.Dec(FCurrent);
if FCurrent = 0 then
FEvent.Sign;
end;
function TCountdownEventEx.IsFinish: boolean;
begin
Exit(FCurrent <= 0);
end;
procedure TCountdownEventEx.Wait(aTimeout: cardinal);
begin
FEvent.Wait(aTimeout);
end;
I've used the same example as in Delphi help and it seems to work...
program TCountdownEvent_example;
{$APPTYPE CONSOLE}
uses
SysUtils,
BB.Sync,
Classes;
var
RunwayFlag: TCountdownEventEx;
type
TThreadIgnite = class(TThread)
private
procedure Execute; override;
end;
procedure TThreadIgnite.Execute;
begin
RunwayFlag.Wait(INFINITE);
Writeln('Ignited');
end;
var
Thread: TThreadIgnite;
begin
RunwayFlag := TCountdownEventEx.Create(200);
Thread := TThreadIgnite.Create(True);
Thread.Start;
while not RunwayFlag.IsFinish do
begin
RunwayFlag.Signal;
Writeln(RunwayFlag.Current);
end;
end. { Put breakpoint here to see the console output. }
No comments:
Post a Comment