I’m trying to use the invokeAsync/invokeLater pair to do come computation but the later part isn’t going to be doing anything to anything external so I’ve come across a problem - passing the data computed by invokeAsync or invokeLater to something outside the original system.util.invokeAsynchronous call.
See the below function:
def doAsyncLater(funcAsync, funcLater=None):
import time
timeStart = time.time()
timeEnd = 0
def doAsync():
def doLater(timeEnd = timeEnd):
funcChange("after")
timeEnd = time.time()
if funcLater is not None:
funcLater()
funcAsync()
system.util.invokeLater(doLater)
system.util.invokeAsynchronous(doAsync)
return [timeEnd, timeStart]
In this example I’m trying to create a more generic invoke async/later pair for others to use that will calculate the time taken. Right now my issue is that timeEnd is always 0. I’ve done some reading about Python and how it deals with this and from that it seems like it somehow may not be possible to do what I want here, but I’m hoping someone here has an idea to get around this.
See this thread and the later.py script linked within. You’d want to look at the assignLater() function.
As for timing, simply instantiate a new java.lang.Date object at suitable points, and subtract their raw milliseconds (via .getTime()) to yield a millisecond interval. If you need more precision, consider using java.lang.System.nanoTime(), but beware of poor multiprocessor implementations.
I don’t know if that’s exactly what I’m trying to do; my problem here is that I can’t seem to get anything out of system.util.invokeAsynchronous - it seems to break ties with the original program.
I did find a decent solution that should have jumped out of me earlier. I need to do whatever I’d do with the time result or whatever inside the doLater function, or else… well, thats the reason I have a doLater (duh). I also had an issue with “communication” between the doAsync & the doLater function, so I have an array to pass whatevers needed between the two.
Here it is for those interested:
def doAsyncLater(funcAsync, funcLater=None, funcChange = None):
import time
timeStart = time.time()
funcChange = funcChange if funcChange is not None else lambda x: None
args = {}
def doAsync(args = args):
def doLater(args = args):
funcChange("after")
timing = {"start": timeStart, "end": time.time(), "time": time.time() - timeStart}
if funcLater is not None:
funcLater(args, timing)
funcChange("before")
funcAsync(args)
system.util.invokeLater(doLater)
system.util.invokeAsynchronous(doAsync)
Uhm, yes. It does and must. The whole point is to not hold up the original thread. (Which is running the GUI -- holding it up freezes the client.)
Whatever code you want to run after the asynchronous task completes needs to be in its own function called from the tail of the async task. If said code needs to interact with the GUI, it needs to be launched with invokeLater.