# GUI no respondse when invokeAsynchronous the COM IO fucntion

**URL:** <https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342>\
**Category:** Ignition\
**Tags:** ignition81\
**Created:** [January 18, 2021, 1:32am UTC](https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342 "2021-01-18T01:32:35Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Park](https://avatars.discourse-cdn.com/v4/letter/p/e79b87/32.png) [@Park](https://forum.inductiveautomation.com/u/Park)\
**Post date:** [January 18, 2021, 1:32am UTC](https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342/1 "2021-01-18T01:32:35Z")

</div>

Hi, I did a function to monitor COM port , and run this in system.unitl.invokeAsynchronous. but GUI has no response when I click a button to execute this function (OpenCOMDevice in my attached code), meanwhile I see it can receive the bytes from COM port and write to tags in background. can anyone help on this? I searched a lot topic about this, but no luck

```auto
import sys, jarray, traceback
from java.lang import String, Thread
from java.util import Date
from org.apache.commons.lang3 import StringEscapeUtils

logger = system.util.getLogger('clientCOMIO')

def OpenCOMDevice(devicepath):
	system.tag.writeBlocking(['[default]%s/Active' % devicepath], [1])
	system.util.invokeAsynchronous(COMReadAndWrite(devicepath),devicepath)
	logger.debug("device opened:" +devicepath)
def CloseCOMDevice(devicepath):
	system.tag.writeBlocking(['[default]%s/Active' % devicepath], [0])
	logger.debug("device closed:" +devicepath)

def COMReadAndWrite(devicepath):
	values=system.tag.readBlocking(['[default]%s/Port' % devicepath,'[default]%s/BitRate' % devicepath,'[default]%s/HandShake' % devicepath,'[default]%s/FlowControl' % devicepath\
	,'[default]%s/Parity' % devicepath,'[default]%s/DataBit' % devicepath,'[default]%s/StopBit' % devicepath])
	port = values[0].value
	bitrate = values[1].value
	handshake = values[2].value
	flowcontrol = values[3].value
	parity = values[4].value
	databit = values[5].value
	stopbit = values[6].value
#	port = system.tag.read('[default]%s/Port' % devicepath).value
#	bitrate=system.tag.read('[default]%s/BitRate' % devicepath).value
#	handshake=system.tag.read('[default]%s/HandShake' % devicepath).value
#	flowcontrol=system.tag.read('[default]%s/FlowControl' % devicepath).value
#	parity=system.tag.read('[default]%s/Parity' % devicepath).value
#	databit=system.tag.read('[default]%s/DataBit' % devicepath).value
#	stopbit=system.tag.read('[default]%s/StopBit' % devicepath).value
	started = False
	try:
		system.serial.configureSerialPort(port, bitrate, databit,handshake, flowcontrol, parity, stopbit)
		system.serial.openSerialPort(port)
		active = system.tag.readBlocking(['[default]%s/Active' % devicepath])[0].value
		while active:
			receivedbytes = system.serial.readBytes(port,32,1000)
			started=-1
			for i in range(len(receivedbytes)):
				if receivedbytes[i] <> 0:
					started=i
					break
			if started > -1:
				ended = -1
				for i in range(started,len(receivedbytes)):
					if receivedbytes[i]==0:
						ended=i
						break
				
				# verify received data
				
				system.tag.writeAsync(['[default]%s/LastTrafficTime' % devicepath,'[default]%s/Received' % devicepath,'[default]%s/LastError' % devicepath], [Date(),receivedbytes[started:ended],''],None)
			send=system.tag.readBlocking(['[default]%s/Send' % devicepath])[0].value
			if (len(send)>0):
				system.serial.writeBytes(port,send)
				system.tag.writeAsync(['[default]%s/Send' % devicepath], [''])
			active = system.tag.readBlocking(['[default]%s/Active' % devicepath])[0].value
			Thread.sleep(100)

	finally:
		system.serial.closeSerialPort(port)	
		CloseCOMDevice(devicepath)

```

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [January 18, 2021, 3:24am UTC](https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342/2 "2021-01-18T03:24:48Z")

</div>

> [@Park](#):
>
> system.util.invokeAsynchronous(COMReadAndWrite(devicepath),devicepath)

This function accepts no parameters for the function your pating into it. Also, currently you are actually running the function openCOMDevice _in the gui thread_. You need to pass in the function definition (ie without parenthesis, otherwise you will be executing the function and passing in its return value.

To pass in your parameters, you need to rely on Python's... Inherited scope variables.. I can't remember the name, @pturmel?

---

<div class="post-metadata">

**Author:** ![Park](https://avatars.discourse-cdn.com/v4/letter/p/e79b87/32.png) [@Park](https://forum.inductiveautomation.com/u/Park)\
**Post date:** [January 18, 2021, 3:59am UTC](https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342/3 "2021-01-18T03:59:41Z")

</div>

> [@nminchin](#):
>
> You need to pass in the function definition (ie without parenthesis, otherwise you will be executing the function and passing in its return value

Hi Nick, thank you very much, I know the reason now.  
I modified the code to use a global variable, replace for the parameter of function openCOMDevice. Code works now. Code as below:

```auto
import sys, jarray, traceback
from java.lang import String, Thread
from java.util import Date
from org.apache.commons.lang3 import StringEscapeUtils

logger = system.util.getLogger('clientCOMIO')
devicepath=''
def OpenCOMDevice(device):
	global devicepath
	system.tag.writeBlocking(['[default]%s/Active' % device], [1])
	devicepath=device
	system.util.invokeAsynchronous(COMReadAndWrite)
	logger.debug("device opened:" +devicepath)
def CloseCOMDevice(device):
	system.tag.writeBlocking(['[default]%s/Active' % device], [0])
	logger.debug("device closed:" +device)

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 18, 2021, 12:53pm UTC](https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342/4 "2021-01-18T12:53:30Z")

</div>

> [@nminchin](#):
>
> Inherited scope variables… I can’t remember the name

"Closures"

You can also use default parameters for an inline-defined function. I recommend just using my later.py script module.

> [@Update GUI via Asynchronous thread](http://forum.inductiveautomation.com/t/update-gui-via-asynchronous-thread/9666/3):
>
> Since this sort of thing pops up often, I created a set of wrappers that simplify this stuff, and allows you to directly use functions in your script modules. The wrappers take care of stuffing the arguments you supply into a temporary fuction’s default argument. For your case, try assignLater(). Nick’s example becomes: # In a script module in your project: import shutil def fileTransfer(label): path = system.file.openFile() newPath = "F:\NewFolder" shutil.copy2(path, newPath) sh…

---

<div class="post-metadata">

**Author:** ![code\_skin](https://avatars.discourse-cdn.com/v4/letter/c/43a26b/32.png) [@code\_skin](https://forum.inductiveautomation.com/u/code_skin)\
**Post date:** [January 18, 2021, 1:15pm UTC](https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342/5 "2021-01-18T13:15:06Z")

</div>

For anyone reading this in the future you can pass parameters to the system.util.invokeAsynchronous() with the help of **partial** library

```auto
def func1(param1):
     # do stuff		

from functools import partial		
param1 = 'test'				
system.util.invokeAsynchronous(partial(func1, param1)) # note; call func1 without parenthesis ()

```

---

<div class="post-metadata">

**Author:** ![Park](https://avatars.discourse-cdn.com/v4/letter/p/e79b87/32.png) [@Park](https://forum.inductiveautomation.com/u/Park)\
**Post date:** [January 19, 2021, 12:35am UTC](https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342/6 "2021-01-19T00:35:47Z")

</div>

Great!, this really help lots.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [January 19, 2021, 7:22pm UTC](https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342/7 "2021-01-19T19:22:13Z")

</div>

Also, for posterity, as of 8.0.15 you can pass `args` and `kwargs` objects to `system.util.invokeAsychronous` directly.

---

<div class="post-metadata">

**Author:** ![code\_skin](https://avatars.discourse-cdn.com/v4/letter/c/43a26b/32.png) [@code\_skin](https://forum.inductiveautomation.com/u/code_skin)\
**Post date:** [January 19, 2021, 7:49pm UTC](https://forum.inductiveautomation.com/t/gui-no-respondse-when-invokeasynchronous-the-com-io-fucntion/42342/8 "2021-01-19T19:49:03Z")

</div>

sweet!
