writeBlocking in a Vision Client

I was reading through one of the Knowledge Base articles (https://support.inductiveautomation.com/hc/en-us/articles/5876672308877-Vision-Client-Unresponsive) and came across the section "Check for Any Blocking Functions Running Directly in the Client". This section states:

You generally do not want to run blocking functions in a Vision Client, especially if there are multiple such scripts in the Client. As an example, Java Swing’s GUI is generated with a single thread. This thread is called the event dispatch thread (EDT) . It is generally bad practice to run blocking scripts in the Vision Client because this can block the EDT.

With this, should I be using system.tag.writeAsync for the majority of writes that I need to do in a Vision window (if a dropdown changes, go write the new value in the PLC)? Should I be creating bindings that I update and have Ignition automatically update the PLC variable?

What is best practice for writing values in a Vision Client?

This. You should use binding (direct or indirect) whenever possible.

In almost all cases tag write functions can, and IMHO should, be replaced by a custom property with a bi-directional binding.

For instance:

system.tag.write*(['[default]path/to/value1'],[100])

Could also be something like:

event.source.customPropertyValue1 = 100

Where customPropertyValue1 is bound to [default]path/to/value1

In the event that you need to write a value to a tag in script and time is not critical then usesystem.tag.writeAsync()

If you need to insure that the values are written prior to continuing with another action, then system.tag.writeBlocking() is needed. In this case you can utilize system.util.invokeAysnchronous() to run on a background thread. If you need to effect changes to UI components, then you can utilize system.tag.invokeLater() to accomplish that.

Here is a discussion on a similar topic, it relates to V7.9 but the concepts still apply. writeSyncronous() and writeAllSyncronous() have been replaced with wrtieBlocking() in V8.

The recommendation is for the EDT, the foreground thread. All UI events run on this foreground thread. If you run a system function that has to contact the gateway, the foreground of the Vision client stalls for the round trip. If you are making such calls in many events all over the place, the UI will lag, especially on a WAN or VPN.

The deprecated system.tag.write() call is one of the few that isn't a problem, because it is really Async without the callback. Fire and forget, so to speak, and doesn't stall the UI. (It may be deprecated, but I don't see any of the deprecated functions going away any time soon.)

Note that the actionPerformed event on a button, because it is user-initiated, is generally an OK place for one or two such calls. Anything more complicated should be delegated to a background thread, where there won't be any UI interaction. However, background threads cannot update the UI themselves--deadlock risk. See this topic for more information: