Improve or warn about ReceiveWait and creating task with function
Hello, i just figured out that ReceiveWait will also receive internal messages. Lets say i create a task and say execute the Execute procedure:
CreateTask(TMyOmniWorker.Create(True)).MonitorWith(FOmniEM).Run(@TMyOmniWorker.Execute);
Inside the Initialize function i make a checkup if the task is allowed to process:
LFound := False;
repeat
// This will also receive the @TMyOmniWorker.Execute message!
task.Comm.ReceiveWait(LMessage, 1000 * 5);
LFound := (((LMessage.MsgID = MSG_CONTINUE_TASK) or (LMessage.MsgID = MSG_QUIT_TASK)) and (LMessage.MsgData[0].AsInt64 = task.UniqueID));
/// START Execute Fix
if not LFound then
task.Comm.OtherEndpoint.Send(LMessage);
until LFound;
Here the problem appears. It took some time to figure it out. The ReceiveWait function catches the Execute message and removes it from the internal list. In the end the Initialize function is finished, but the Execute procedure gets never called. Obviously this is really clear if you read this, but you have to know that the same message channel is used.
In order to "fix" the problem i receive the Execute message and send it again to the TMyOmniWorker/OtherEndpoint.
http://geskill.bplaced.net/hp/other/OmniWorkerTestwithMonitor.zip
best regards
Good catch! I think this should be considered a bug and should be fixed.
BTW, your approach looks a bit weird to me. Why do you call the Execute if you then immediately check if you can run it at all? Can't you just call Run without a parameter and then do 'task.Invoke(Execute)' when you actually need it?
I don't want to make the demo too complex ;)
Just add the IOmniThreadPool and set MaxExecuting := 1. Followed by:
CreateTask(TMyOmniWorker.Create(True)).MonitorWith(FOmniEM).
Schedule(FThreadPool).Invoke(@TMyOmniWorker.Execute)
Same result. Now, the tasks are inside the queue and at the time a specific task is able to run (because all previous tasks have been finished), the time has passed and the task caller is maybe gone and this specific task is unnecessary to be done.
http://geskill.bplaced.net/hp/other/OmniWorkerTestwithMonitorandThreadPool.zip
PS: Now even more internal calls have to be redirected from ReceiveWait ^_^
OK, that is a sensible argument.