Friday, November 13, 2009

OmniThreadLibrary 1.04 alpha

Not yet beta as I still have to fix few TODOs …

Get it here.


  • Changed semantics in comm event notifications! When you get the 'new message' event, read all messages from the queue in a loop!
  • Message is passed to the TOmniEventMonitor.OnTaskMessage handler. There's no need to read from Comm queue in the handler.
  • Exceptions in tasks are now visible by default. To hide them, use IOmniTaskControl.SilentExceptions. Test 13_Exceptions was improved to demonstrate this behaviour.

Other changes

  • Works with Delphi 2010.
  • Default communication queue size reduced to 1000 messages.
  • Support for 'wait and send' in IOmniCommunicationEndpoint.SendWait.
  • Communication subsystem implements observer pattern.
  • WideStrings can be send over the communication channel.
  • New event TOmniEventMonitor.OnTaskUndeliveredMessage is called after the task is terminated for all messages still waiting in the message queue.
  • Implemented automatic event monitor with methods IOmniTaskControl.OnMessage and OnTerminated. Both support 'procedure of object' and 'reference to procedure' parameters.
  • New unit OtlSync contains (old) TOmniCS and IOmniCriticalSection together with (new) OmniMREW - very simple and extremely fast multi-reader-exclusive-writer - and atomic CompareAndSwap functions.
  • New unit OtlHooks contains API that can be used by external libraries to hook into OTL thread creation/destruction process and into exception chain.
  • All known bugs fixed.

New demos

  • 25_WaitableComm: Demo for ReceiveWait and SendWait.
  • 26_MultiEventMonitor: How to run multiple event monitors in parallel.
  • 27_RecursiveTree: Parallel tree processing.
  • 28_Hooks: Demo for the new hook system.
  • 29_ImplicitEventMonitor: Demo for OnMessage and OnTerminated, named method approach.
  • 30_AnonymousEventMonitor: Demo for OnMessage and OnTerminated, anonymous method approach.

A teaser from demo 30

procedure TfrmAnonymousEventMonitorDemo.btnHelloClick(Sender: TObject);
btnHello.Enabled := false;
FAnonTask := CreateTask(
procedure (task: IOmniTask) begin
task.Comm.Send(0, Format('Hello, world! Reporting from thread %d',
procedure(const task: IOmniTaskControl; const msg: TOmniMessage) begin
lbLog.ItemIndex := lbLog.Items.Add(Format('%d:[%d/%s] %d|%s',
[GetCurrentThreadID, task.UniqueID, task.Name, msg.msgID,
procedure(const task: IOmniTaskControl) begin
lbLog.ItemIndex := lbLog.Items.Add(Format('[%d/%s] Terminated',
[task.UniqueID, task.Name]));
btnHello.Enabled := true;
FAnonTask := nil;


  1. Anonymous21:20

    Awesome news! I've been using OTL 1.03 in a deployed product with great success. I saw the huge number of changes and was looking forward to a new release.

    I hope I'll have time to test 1.04 alpha or beta this month!

    Thanks again for the big update!

  2. Bill Miller19:00

    I am trying to adapt your background file search demo to add file path, file name, file type, file date, file time and file size to a TListView. All the above seems to work nicely as I eliminated the stringlist and add the file info from the search record in the ScanFolder method. The problem is I added a stop button and often the thread is not stopped and the app hangs when I click the button. How can I stop the search and terminate the thread with FScanTask.Terminate with a TButton Click? I do not understand why this works with the FormCloseQuery event but not on a button click?

    procedure TfrmBackgroundFileSearchDemo.Stop1Click( Sender: TObject );
    if assigned( FScanTask ) then
    Stop1.Enabled := False;
    FScanTask.Terminate; // APP Hangs here
    FScanTask := nil;
    Scan1.Enabled := True;
    Scanning1.EditLabel.Caption := 'Scanning Stopped ...';
    Scanning1.Text := '';

  3. Are you by any chance running some mixture of old and new OTL sources? This approach works fine with release 457.

    I tested with a simpler code: Started with background file search demo and changed btnScan.Enabled := false into

    btnScan.Caption := 'Stop';
    btnScan.OnClick := StopScan;

    in btnScanClick method. Then I wrote StopScan method:

    procedure TfrmBackgroundFileSearchDemo.StopScan(Sender: TObject);
    FScanTask.Terminate; // APP Hangs here
    FScanTask := nil;
    btnScan.Caption := 'Start';
    btnScan.OnClick := btnScanClick;

    And I added

    btnScan.Caption := 'Start';
    btnScan.OnClick := btnScanClick;

    at the end of OTLMonitorTaskTerminated.

    The code works as expected.

  4. Bill Miller00:01

    Thanks for your reply. Your code works fine here with no problem. I guess I still do not understand why the Stop1Click code failed at FScanTask.Terminate.

  5. If you zip your project and put it somewhere, I'll take a look at the code.