unit BlockAsyncForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, BlockToAsyncBuf, PrimeRangeThread;
const
MaxCount = 20;
type
TBlockAsyncFrm = class(TForm)
Label1: TLabel;
StartRangeEdit: TEdit;
Label2: TLabel;
EndRangeEdit: TEdit;
SubmitBtn: TButton;
ResultsMemo: TMemo;
procedure FormCreate(Sender: TObject);
procedure SubmitBtnClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FItemsInTransit: integer;
FBuf: TBlockToAsyncBuf;
FWorkerThread: TPrimeRangeThread;
procedure BufRead(Sender: TObject);
procedure BufWrite(Sender: TObject);
public
{ Public declarations }
end;
var
BlockAsyncFrm: TBlockAsyncFrm;
implementation
{$R *.DFM}
procedure TBlockAsyncFrm.FormCreate(Sender: TObject);
begin
FWorkerThread := TPrimeRangeThread.Create(true);
FBuf := TBlockToAsyncBuf.Create(Self);
with FBuf do
begin
{ Note that these changes will take effect before
events from this component could possibly occur }
OnRead := BufRead;
OnWrite := BufWrite;
end;
SetThreadPriority(FWorkerThread.Handle, THREAD_PRIORITY_BELOW_NORMAL);
with FWorkerThread do
begin
Buf := FBuf;
Resume;
end;
end;
procedure TBlockAsyncFrm.SubmitBtnClick(Sender: TObject);
var
Request: PRangeRequestType;
Temp: integer;
begin
New(Request);
try
Request.Low := StrToInt(StartRangeEdit.Text);
Request.High := StrToInt(EndRangeEdit.Text);
if Request.Low > Request.High then
begin
Temp := Request.Low;
Request.Low := Request.High;
Request.High := Temp;
end;
if FBuf.AsyncWrite(Request) then
begin
Request := nil;
SubmitBtn.Enabled := false;
Inc(FItemsInTransit);
end;
finally
if Assigned(Request) then Dispose(Request);
end;
end;
procedure TBlockAsyncFrm.BufWrite(Sender: TObject);
begin
{ Buffer has indicated that there is space for us to write }
SubmitBtn.Enabled := true;
end;
procedure TBlockAsyncFrm.BufRead(Sender: TObject);
var
Reply: TStringList;
begin
{ We have received a notification that we may read. }
Reply := TStringList(FBuf.AsyncRead);
if Assigned(Reply) then
begin
Dec(FItemsInTransit);
ResultsMemo.Lines.BeginUpdate;
ResultsMemo.Lines.AddStrings(Reply);
while ResultsMemo.Lines.Count > MaxCount do
ResultsMemo.Lines.Delete(0);
ResultsMemo.Lines.EndUpdate;
end;
end;
procedure TBlockAsyncFrm.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
CanClose := true;
if FItemsInTransit > 0 then
if MessageDlg('Some requests in transit, close anyway?', mtWarning,
mbOKCancel, 0) <> mrOK then
CanClose := false;
end;
procedure TBlockAsyncFrm.FormDestroy(Sender: TObject);
begin
FWorkerThread.Terminate;
FBuf.ResetState;
FWorkerThread.WaitFor;
FBuf.Free;
FWorkerThread.Free;
end;
end.