How to know when invokeasynchronous process has ended?

Is there anyway to know if an invoke-asynchronous has ended its process?

Example:

for i in range(0,10): def print_t (i): print i invokeasynchronous(i)

how will i know if it has finish printing i in range of 10?

Thank you!

I’m not sure what your code is supposed to do. Can you test it and get it working and post it again?

system.util.invokeAsynchronous ends its process when the function it calls completes running. So you know it ends when the last statement in the function executes.

You will know when it has finished printing i in range of 10 when you see the numbers 0 through 9 output in the console.

Are you asking how to detect in your code that calls system.util.invokeAsynchronous when the thread that is created by system.util.invokeAsynchronous finishes running? You can’t, well not directly. And normally there is no reason to. I’ve never needed to. Is there a reason you need to?

Best,

If you google java thread synchronization or jython thread synchronization, it’ll blow the top of your head off. For simple tasks in Ignition, consider using a boolean client tag that the called function sets in the end of a try-finally block.

Okay Nick. Sorry my syntax is wrong.

What we are trying to do is to detect when asynchronous finished running or those task that are executed using asynchronous finished running. For example, i’m looping through a list of files, and every file on that list i need to parse and save the data to DB. And it takes a very long time to parse the file without asynchronous. We have to detect when asynchronous finished parsing those files and do something after that. But what;s happening is the task that should be executed when asynchronous is done is being executed without waiting for asynchronous to finish.

this is what we want to happen:

[code]for file in filelist:
parse every file and save to DB (long process without async)

do something after parsing the files
[/code]

[quote=“ella_ramos”]Okay Nick. Sorry my syntax is wrong.

What we are trying to do is to detect when asynchronous finished running or those task that are executed using asynchronous finished running. For example, i’m looping through a list of files, and every file on that list i need to parse and save the data to DB. And it takes a very long time to parse the file without asynchronous. We have to detect when asynchronous finished parsing those files and do something after that. But what;s happening is the task that should be executed when asynchronous is done is being executed without waiting for asynchronous to finish.

this is what we want to happen:

[code]for file in filelist:
parse every file and save to DB (long process without async)

do something after parsing the files
[/code][/quote]

How about this?

def process_files():
	for file in filelist:
   		parse every file and save to DB (long process without  async)

	do something after parsing the files

system.util.invokeAsynchronous(process_files)

Hello Kevin,

Yes. That is what we are currently doing.
So for every thread created by asynchronous we want to be able to check if all those threads have finish their execution before we execute another task.

Hi ella,

Kevin’s code only creates one single background thread to parse and handle all the files – and then whatever you want to do after that. Keven’s code is perfect for what you are saying you need, unless you have more information to share … ?

Do you want to start a separate thread to handle each file? If that is the case you should look at pa.thread.multiTask(functions, endFunction). It takes two arguments, a list of functions, and a function called the endFunction. Each function in the list is executed separately in its own thread, and when all the functions in the list have completed executing the endFunction executes.

So with pa.thread.multiTask you could process multiple files asynchronously (each in its own thread), and still be able to take action when they have all completed by supplying a function to execute once they complete. See the examples in the documentation for pa.thread.multiTask.

Best,

Yeah, I've searched about it. I think threading will do the job.

Thanks Nick for the suggestion.
Will try to find other solution before we resort to buying new module.

As you wish. Here’s an example of processing files concurrently with pa.thread.multiTask:

[code]def parseAndSaveFileToDB(file):
#parse file and save to DB

def makeFileFunction(file):
def fileFunction():
parseAndSaveFileToDB(file)
return fileFunction

functions = []
for file in filelist:
functions.append(makeFileFunction(file))

def endFunction():
print “all files have been parsed and saved to the database”

pa.thread.multiTask(functions,endFunction)[/code]The code above could be rewritten much shorter and nicer like this:[code]def parseAndSaveFileToDB(file):
#parse file and save to DB

functions = [lambda file=file: parseAndSaveFileToDB(file) for file in filelist]

def endFunction():
print “all files have been parsed and saved to the database”

pa.thread.multiTask(functions,endFunction)[/code]Best,

1 Like

If you want to run some script after each individual file is processed you could do something like this:

[code]
for file in filelist:

def parseAndSaveFile(oneFile):
	parse it
	save it
	
	def runWhenDone():
		print "%s has been processed" % oneFile.name
		
	system.util.invokeLater(runWhenDone)

system.util.invokeAsynchronous(file)[/code]

Hello Nick,

Thank you for the suggestions below.

This is what we did. We use python threading.

[code]def parse_save(file,filefolder):
parse stuff here and save to db

threads = []
for filefolder in FileNameList:
for file in os.listdir(filefolder):
t = Thread(target=parse_save, args=(file,filefolder, ))
threads.append(t)
t.start()

for t in threads:
t.join()

do_something_after_all_threads_are_done()[/code]

This works!

thanks everyone for your inputs.

@JGJohnson

Thank you for your input. At first that was what we were doing. But we need to make sure that all threads are done processing before we execute the next task.