What is the correct procedure to terminate tasks if you need to cancel what they are doing?
I have a procedure that starts two tasks that can take 20-30 seconds each as they each process a dataset and create an output file. If I want to cancel the output and close the dialog I have coded this in my formclosequery:
procedure TCCC100.FormCloseQuery(
Sender : TObject;
var CanClose : Boolean);
begin
inherited;
GlobalOmniThreadPool.CancelAll;
if Assigned(InventoryTask) then
InventoryTask.Terminate;
if Assigned(PartTask) then
PartTask.Terminate;
if Assigned(CountTasks) then
while CountTasks.Value > 0 do
Application.ProcessMessages;
PartTask := nil;
InventoryTask := nil;
Terminated := true;
end;
The dialog gets stuck in an endless loop waiting for CountTasks.Value to reach 0;
The task is setup as such:
InventoryTask := CreateTask(LoadInventoryRecords, 'LoadInventoryRecords')
.OnMessage(InventoryHandleTaskMessage)
.OnTerminated(InventoryHandleTaskTerminated)
.SetParameter('TaskNumber', 1)
.Schedule(GlobalOmniThreadPool);
and the OnTerminate method is:
procedure TCCC100.InventoryHandleTaskTerminated(
const task : IOmniTaskControl);
begin
LogMessages(Format('[%d/%s] %d|%s', [task.UniqueID, task.Name, 1, 'Inventory finished.']));
CountTasks.Decrement;
end;
When the FormCloseQuery calls InventoryTask.Terminate, does that not tell the task to run its Terminated method and then decrement CountTasks as shown above? From what I can tell, it skips the OnTerminate method so i get stuck in the loop. If I comment out the loop waiting for CountTasks to reach zero, I get an exception when I assign nil to the two tasks created.
Guess I need a lesson in cleaning up tasks!
Thanks in advance.
John