RealSleep(IintSeconds : Integer) // RealSleep // The Navision SLEEP-command blocks automations. // This Sleep does NOT block automations because it uses the WSH shell command // PARAMETERS: // IintSeconds : No. of seconds to do a sleep IF IintSeconds <= 0 THEN EXIT; LtxtCRLF := 'xx'; LtxtCRLF[1] := 10; LtxtCRLF[2] := 13; LtxtTempVBS := GetTemporaryFilename(TRUE,'vbs'); Lfil.WRITEMODE(TRUE); Lfil.TEXTMODE(TRUE); Lfil.QUERYREPLACE(FALSE); Lfil.CREATE(LtxtTempVBS); Lfil.WRITE(STRSUBSTNO('WScript.Sleep %1',IintSeconds * 1000)); Lfil.CLOSE; DosShell('cscript.exe //nologo ' + LtxtTempVBS,0,TRUE); ERASE(LtxtTempVBS);
Comments
It is time already to change mentality from single flow programming to multi thread event driven programming - you write your code in triggers that respond to some events in the environment your program is living in, the order of those events is a priori unpredictable.
So in case you want to do something like Object.RunAndWaitForResponse where response is a firing of some trigger Object.OnResponseEvent
you should change your program logic from to and trigger Object.OnResponseEvent code:
The problem with this code in Navision is the 3 lines are run and Navision continues with other things WITHOUT waiting.
In general you C/AL code prepares something and then runs the automation.
The command that calls the automation returns immediately WITHOUT waiting for the end of the task the automation should do.
So the C/AL command after the automation-call is run but the automation has not finished yet.
How can I let Navision wait for it?
The only thing I found is:
and in some event-trigger of the automatin I put:
If you found a better wat, let us know.
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
Exactly that's why you do not put any code after (i wrote EXIT to indicate that there is no code below) but instead place the rest of your code (which is supposed to be executed upon getting the response) in the corresponding trigger which receives the response from the object
there is no point in putting the command where it does not belong to be Put the command in the trigger
In the last case, if it is a user session, the user can start doing other things. If it is a NAS, other triggers can be fired. So you are not sure that your event-trigger is fired.
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
again should not NAS be able to executed many tasks simultaniously ? That's exactly the problem with your REPEAT UNTIL loop - it prevents NAS from responding to new events while your task is being processed
To be sure define automation object in a single instance codeunit so it continues to sit in memory even after the trigger is executed.
Like :
-C/AL command.
-automation call that should process something and only come back when it has finished. If I can't give a parameter to let the automation wait for the end. So I need to put some code after the automation-call to wait until it has finished.
-C/AL command that ONLY should execute when the automation has finished.
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
Please can you explain what do you mean by that ?
For example:
i create a form and define a single instance codeunit variable MyCU inside the form and then from form's button i call codeunit's function that creates an automation object MyAO defined in that codeunit and asks that object to do some tasks. I can click the button multiple times and if codeunit is designed to create multiple MyAO and run them then they will execute simultaniously.
When i close the form my understanding is that MyCU variable is destroyed upon exit from the form but MyAO object still exists and continues user's task
Even more : ALL objects referencing it will use THE SAME instance.
You can test that by defining a global in your singleinstance codeunit and running and object that gives a value to it and then running another objects that asks the value of it. (giving and asking the value must be done through functions in the singleinstance codeunit.
Navision NEVER will execute code at the same time. Like Windows (with a single core singe processor): it seems to be multitasking but in reality it is taskswapping so fast that it seems to be multitasking.
"not re-entrant":
Example : you launched 2 times a pdf-printing automation (in a singleinstance codeunit) and you are waiting for the finishing-event of both. The finishing-event will be called twice (once for each pdf) but in that event, you will NEVER know which of the 2 has finished first! This is the reason you need to wait for the first to finish before launching the second. And thus my repeat-until to wait for it.
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
When calling pdf printing one can check if it is not in process of printing another pdf and ask the user if he wants to launch the second one. If the user chooses to start the second pdf printing then one needs to use a separate automation object for it.
I do agree however that it is much easier to program single-flow than to program multitasking and your REPEAT UNTIL is easier to write. But the idea of asking repeatedly if task is completed is ridiculous - when you give a task to a person you don't come to him every minute asking if he completed the task, instead you simply ask him to report you back when he completes his task
It is a NAS that does this work. The NAS would just continue to work on something else (maybe for a long time) and the event-trigger would be postponed a lot because it wouldn't be triggered until the NAS isn't running and C/AL anymore. So this is the reason I didn't want to use your system (although it is more programmatically more correct).
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
in codeunit 1 on NAS trigger call your single instance codeunit. In codeunit write the following in OnRun trigger:
OnRun()
then in OnTimer tigger:
So after executing OnRun the NAS can process other requests
but your service is now installed and timer will be called every second to check if there are tasks to be executed by your service
If a trigger is fired, no other trigger will be fired UNTIL the first taks is finished.
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
the timer trigger is not firing but i believe timer events are stacked into Navision's windows messaging queue. Would be interesting to test it - if i keep my task busy for 1 minute will the trigger fire 60 times right after exiting my task or will it fire just once ?
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!