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
 { Ntese que los cambios tendrn efecto antes de que puedan
 ocurrir los eventos de este componente. }
 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
 { El buffer indica que hay espacio para que podamos escribir }
 SubmitBtn.Enabled := true;
end;
 
procedure TBlockAsyncFrm.BufRead(Sender: TObject);
 
var
 Reply: TStringList;
 
begin
 { Recibimos una notificacin de que podemos leer. }
 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('Hay algunos pedidos procesndose. Desea cerrar de todas formas?', 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.