Not yet beta as I still have to fix few TODOs …
COMPATIBILITY ISSUES
- 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);
begin
btnHello.Enabled := false;
FAnonTask := CreateTask(
procedure (task: IOmniTask) begin
task.Comm.Send(0, Format('Hello, world! Reporting from thread %d',
[GetCurrentThreadID]));
end,
'HelloWorld')
.OnMessage(
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,
msg.msgData.AsString]));
end)
.OnTerminated(
procedure(const task: IOmniTaskControl) begin
lbLog.ItemIndex := lbLog.Items.Add(Format('[%d/%s] Terminated',
[task.UniqueID, task.Name]));
btnHello.Enabled := true;
FAnonTask := nil;
end)
.Run;
end;
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.
ReplyDeleteI hope I'll have time to test 1.04 alpha or beta this month!
Thanks again for the big update!
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?
ReplyDeleteprocedure TfrmBackgroundFileSearchDemo.Stop1Click( Sender: TObject );
begin
if assigned( FScanTask ) then
begin
Stop1.Enabled := False;
FScanTask.Terminate; // APP Hangs here
FScanTask := nil;
Sleep(3000);
Scan1.Enabled := True;
Scanning1.EditLabel.Caption := 'Scanning Stopped ...';
Scanning1.Text := '';
end;
end;
Are you by any chance running some mixture of old and new OTL sources? This approach works fine with release 457.
ReplyDeleteI 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);
begin
FScanTask.Terminate; // APP Hangs here
FScanTask := nil;
btnScan.Caption := 'Start';
btnScan.OnClick := btnScanClick;
end;
And I added
btnScan.Caption := 'Start';
btnScan.OnClick := btnScanClick;
at the end of OTLMonitorTaskTerminated.
The code works as expected.
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.
ReplyDeleteIf you zip your project and put it somewhere, I'll take a look at the code.
ReplyDelete