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.