Debug Console not showing 'Live' Outputs

Running Ignition Edge 8.1.11:
I am running a button-triggered script with a for-loop which reads hundreds (at times, thousands) of values from a remote OPC server, and writes the values of tags to a memory array tag. I noticed that my intermediate “print” statements (status of read commands, timestamp, etc.) do not display in the Output Console until AFTER the script is completed. However, if I execute the same script from within the Script Console, I see the outputs immediately. For sake of convenience, I’ve generated some sample code utilizing a sleep() function in order to reproduce my issue:

from time import sleep
timeStart = system.date.now()
i=0
for i in range (10):
	sleep(1)
	timeNow = system.date.now()
	print system.date.millisBetween(timeStart, timeNow)
print "Complete"

When executed in button script, I do not see the 1s increments in the Output Console until after the full 10 sec has elapsed.
However, if this code is executed in the Script Console, I am able to see the 1s intermediate print commands as they are printed.
Modification to the above code which produces results ‘should’ also migrate to my code easily. Any insight as to how to view ‘live’ Console Outputs is much appreciated.

I’m guessing the debug output console just can’t update until your script is done blocking the UI thread. If it’s long running and does a bunch of blocking operations you should probably figure something else out, even if that’s just running it async and trying to keep additional button presses from happening while it runs.

1 Like

Use system.util.invokeAsynchronous() to run the function in the background and use a logger from system.util.getLogger() instead of print.

And absolutely do not call any component methods from that background thread. More information here:

Thanks for the tips! And, also for bearing with me (always in training…)
I initially experimented with invokeAsynchronous(), but obviously had a fundamental misunderstanding of how to implement. The link provided (along with a few others, below) helped with some fundamentals:
DOC81/Project+Library
DOC81/User+Defined+Functions
DOC81/Component+Methods

In my example provided, I was able to prevent the UI from locking up (and able to see updates in the Output Console during execution) by creating a script called “myFuncs” in the Project Library w/ the following:

def runProg():
	from time import sleep
	timeStart = system.date.now()
	i=0
	for i in range (10):
		sleep(1)
		timeNow = system.date.now()
		logger = system.util.getLogger("myFuncsLogger")
		logger.info(str(system.date.millisBetween(timeStart, timeNow)))
	logger.info("Complete")

Then, actionPerformed button script was updated to contain:

system.util.invokeAsynchronous(myFuncs.runProg)

Output Console is updating as expected. Not withstanding my limited ‘application-specific info’, let me know if you would recommend to execute any of the above any differently.
Re: my original task, I’m now passing relevant variables to the function, and working on preventing additional button presses during execution of prior button-press. Cheers!

Do avoid any form of sleep() in production code. Technically permitted in asynch threads (including Perspective events), but generally implies a patch over a race condition.

I recommend, in the button’s actionPerformed method, before lauching the background thread, that you set the button’s enable to false. At the end of the background thread, preferably in a finally clause, you use .invokeLater() to turn it back on.

{ also, get the logger instance once, not in every loop. }

Do avoid any form of sleep() in production code.

Agreed. Actual code is using system.opc.readValue() & system.tag.writeBlocking().

I recommend, in the button’s actionPerformed method, before lauching the background thread, that you set the button’s enable to false. At the end of the background thread, preferably in a finally clause, you use .invokeLater() to turn it back on.

{ also, get the logger instance once, not in every loop. }

Great insight as to my oversight. Much appreciated!

1 Like