Some background:
Basically it comes down to that I want to be able to "execute" the task in the current thread.
Why? -I have a task creator routine, and one time I want the task to be executed immediately in a background task, and at other times I want the task to be scheduled using an IOmniThreadPool.
In the case that I want to use the OmniThreadpool I want do do some output about the task's status, like that it was queued, started, finished or failed.
The task's execution is not yet started at this moment.
So I imagined someting like this:
function WrapIntoPoolTask(const aOriginalTask:IOmniTaskCOntrol):IOmniTaskCOntrol;
begin
if Assigned(aOriginalTask) then
begin
var lPoolProgress:=TaskPoolProgress; // fetch global task pool progress interface
// immediately displays message says its been queued, remember message bookmark
var lMessageBookMark:=lPoolProgress.MessageList.AddMessage(aOriginalTask.Name,pmPaused);
Result:=CreateTask(
procedure (const aTask:IOmniTask)
begin
lPoolProgress.MessageList.UpdateMessage(lMessageBookMark,pmStarted); // update message status
try
aOriginalTask.ExecuteTaskInThisThread; // <<=== So how do I do this?
lPoolProgress.MessageList.UpdateMessage(lMessageBookMark,pmCompleted);
except
lPoolProgress.MessageList.UpdateMessage(lMessageBookMark,pmFailed);
raise;
end;
end
,
'Pooled:'+aOriginalTask.Name
);
end;
end;
Using the UpdateMessage call after performing the original task can be moved to the OnTerminated handler of the IOmniTaskControl interface. I tried that and it works just fine for the thread ending part. It even allows for handling exit codes and exit messages which I like even better.
I think what I am missing here is probably an OnInitialize or OnStartExecution handler to set my pmStarted status.
Question:
- How can I directly execute a tasks "body" from
IOmniTaskCOntrol
or
- how can I add some initialization code to my task after the task was already created. This code should be executed immediatliy prior to executing my tasks original body.
In order to solve my problem I had to change the omnithreadlibrary unit
OtlTaskControla bit.one routine added to
IOmniTaskControl(GUID should change, but I didn'tt)And the implementation added to
TOmniTaskControl:Then my "custom wrapper" routine that actually adds the pool progress handling to whatever the original task was:
And finally, the routine that schedules my wrapped task into the omnipoolthread.
Everything seems to work as expected including the exit code and exit message which are propagated from the inner task to the outer task.
The compiler bug I am referring to is reported here: https://quality.embarcadero.com/browse/RSP-29564 (please vote!)
For those interested: this is what
HandlePoolTaskTerminationlooks like:The
IsFatalExceptionreturns true if the "current" exception is egEAccessViolation,EInvalidOperationand alike.