I am building a modular user interface by embedding smaller UI VIs into SubPanels in my main VI. If I start the VIs with the "Run VI" invoke node, there are no issues:
If, however, I start the VI asynchronously using the `Start Asynchronous Call' VI, the front panel in the SubPanel control doesn't seem to be connected to the running instance of the VI I just started and the front panel in the SubPanel control does not refer to a running VI as I can edit the labels on controls, etc. All VIs are not set to be re-entrant, so I would have expected there to be only one version of the VI running and for it to be the VI in the SubPanel. Furthermore, the help-text for the ``reference out'' connector on the `Start Asynchronous Call' VI says: ``reference out returns reference unchanged.'' Therefore, I would have expected the reference that I pass to `Start Asynchronous Call' to be the same as that which I pass to the SubPanel invoke node.
All of the VIs that I am embedding in this way take no arguments and produce no output, while also running forever (they all are just a bunch of controls with an Event Structure in a While Loop feeding some Functional Globals). Therefore, I was happy to use the `x100' calling code for opening the VI reference as it would call asynchronously, but also stop the VIs and remove them from memory when the parent VI closed. I understand that using `x100' instead of `x80' can be bad if the VIs produce output and finish early but the output is never collected, but since my VIs neither produce output nor stop early I thought this would not be an issue.
I don't need to use the latter approach, but since I'm using it to start other background processes that do not have UI components I was hoping I could have just one approach to start all of my asynchronous tasks and not two. I would also like to better understand why the `Start Asynchronous Call' approach doesn't work.
Unfortunately, I cannot provide my full source code here, but unless there is a simple behavioral answer to my question I am willing to build a minimal working example to show off my issue.
You need to insert the VI after you have opened the reference. I would actually put the insert after the Run Asynchronous and then close the reference.
I'm not entirely certain what you meant, but here are three things I tried.
1. Inserting the `Generic VI Reference' into the SubPanel Invoke Node after the call to `Start Asynchronous Call'
2. Inserting the `Strictly Typed VI Reference' using coercion into the SubPanel Invoke Node after the call to `Start Asynchronous Call' but before the `Strictly Typed VI Reference' was closed.
3. Inserting the `Generic VI Reference' into the SubPanel Invoke Node after the call to `Start Asynchronous Call' but before the `Strictly Typed VI Reference' was closed.
Not one of these three aproaches worked.
Furthermore, I am a little confused -- I had interpreted the `Auto Dispose Ref' boolean in the `Run VI' Invoke Node to basically be the difference between the `0x80' and `0x100' codes used with `Start Asynchronous Call'. If I dispose the reference, the VI will not be ``owned'' by the calling VI and will run in the background as the parent VI closes. However, when I have this value wired to False, the VIs that I start in this manner neverthelss continue running after the calling Main VI is closed.
I just realized that my third attempt did not technically require that the SubPanel Invoke Node be executed after the `Start Asynchronous Call` VI.
Therefore, I tried this, but yet again to no avail:
Furthermore I've tried to use the Invoke Node after the strict reference is opened but before the `Start Asynchronous Call` is executed, yet again to no avail...
Since this has become such a huge pain, I've given up on using the ``call-and-collect'' asynchronous paradigm to deal with my issue.
I am using the ``Run VI'' Invoke Node to run the VIs, and inserting them into the SubPanels afterword as noted in my first post. Then, in the calling VI on my ``exit'' button I trigger a User Event for which all of my subVIs are listening. When they get it, they abort execution. As long as you exit the main VI with the button, there are no longer any background processes sitting around.
This is how I am registering my subVIs for this event:
The VI you see there has the following block diagram:
The first VI icon you see in the above diagram is a fetch from a functional global that stores a reference to this event and is populated by the calling VI on startup.
I think the reason your "Call and collect" paradigm is not working is that you are closing the VI reference straight after you use the "Start Asynchronous call". When using the 0x100 option, you are meant to close the VI reference after waiting for "Wait on Asynchronous Call" to complete i.e. after the VI has run to completion.
Closing the VI reference early will abort execution of the VI.
If you use the 0x80 option (call and forget), you can close the VI reference at any time, and the VI will still run to completion.
I've had a similar issue a couple of times, add a This VI ref will force the front panel to be loaded. It might not be applicable in this case, but still. 🙂