Basic threading helper classes and routines.

  • Simple to use task pool, based on thread pool
  • Task Queue for easy queuing of asynchronous tasks
  • LockFreeStack based on Windows SLISTS
  • TThreadSafeQueue based on linked lists
Cromis Threading download: Version 1.5.0 (09.04.2012)

The demo bellow shows the basic usage of Task Pool.  If you have trouble using the code or have any other questions, please contact me directly using the “Contact” page.

Sample usage:

procedure TfMain.btnStartClick(Sender: TObject);
var
  Task: ITask;
begin
  FTaskPool.DynamicSize := cbDynamicPoolSize.Checked;
  FTaskPool.MinPoolSize := StrToInt(ePoolSize.Text);
  FTaskPool.OnTaskMessage := OnTaskMessage;
  FTaskPool.Initialize;
 
  tmPoolStatus.Enabled := False;
  btnStart.Enabled := False;
  btnStop.Enabled := True;
  FTerminate := False;
 
  while not FTerminate do
  begin
    Task := FTaskPool.AcquireTask(OnTaskExecute, 'RandomTask');
    Task.Values.Ensure('RandomNumber').AsInteger := Random(tbThreadTimeout.Position);
    Task.Run;
 
    pbPoolSize.Position := FTaskPool.PoolSize - FTaskPool.FreeTasks;
    stFreeThreadsValue.Caption := IntToStr(FTaskPool.FreeTasks);
    stPoolSizeValue.Caption := IntToStr(FTaskPool.PoolSize);
    Sleep(Random(tbCreationTimeout.Position));
    Application.ProcessMessages;
  end;
end;
procedure TfMain.OnTaskExecute(const Task: ITask);
var
  Interval: Integer;
begin
  Interval := Task.Values.Get('RandomNumber').AsInteger;
  try
    Task.Message.Ensure('Result').AsInteger := Interval;
    Sleep(Interval);
  finally
    Task.SendMessageAsync;
  end;
end;
procedure TfMain.OnTaskMessage(const Msg: ITaskValues);
var
  Interval: Integer;
begin
  Inc(FTaskCounter);
  Interval := Msg.Get('Result').AsInteger;
  stThreadsFinishedValue.Caption := IntToStr(FTaskCounter);
end;

Change Log

  • 1.5.0
    • 64 bit compiler compatible
  • 1.4.3
    • Added StopAllTasks for TTaskPool
  • 1.4.2 (breaking change)
    • TTaskQueue is not only available as ITaskQueue interface
  • 1.4.1
    • TThreadSafeQueue.AcquireNewItem does not need the lock
  • 1.4.0
    • Added TLockFreeStack based on Windows SLISTS
    • Added TThreadSafeQueue based on linked lists
  • 1.3.7
    • Added ShutdownTimeout (INFINITE by default)
    • Wait for all tasks to finish then shutting down the task pool
  • 1.3.6
    • Added WaitFor so tasks can be waited upon
    • Added Terminated flag for task
  • 1.3.5 (Breaking Change)
    • WaitFor is only available in Delphi 2005 and up
    • Added AsBoolean and AsInterface types for ITaskValue
    • Added ITaskValues.Exists
  • 1.3.4
    • Added “SendMessageAsync” as means of sending messages from tasks
  • 1.3.3
    • Simplified Task Queue and made it faster
  • 1.3.2
    • Added Task Queue class
  • 1.3.1
    • Added DynamicSize property. Pool downsizes if larger than initial size
    • Only MinPoolSize is left (no MaxPoolSize). Can be set before initialize
  • 1.3.0
    • Renamed ThreadPool to TaskPool
    • Added ITask as the main pool object
    • Implemented ITaskValues / ITaskValue as data carrier for more flexibility
  • 1.2.0
    • Change approach to task based. No need to define your own threads anymore
    • Use TStreamStorage as versatile data carrier between threads
  • 1.1.0
    • Use direct notification calls from threads instead of messages
    • Changed names of some procedures
  • 1.0.0
    • Initial implementation of a Thread Pool.