08-28-2009 02:19 PM
Launching a top–level VI from another top–level is a very useful technique which has many applications:
Over the next few posts, we will explore those listed above. Let's start with the basic technique, shown in the snippet above (and in the included VI in LabVIEW 8.2.1 format).
Open the VI to be launched in the current context, then run it using the Run method. Make sure Wait Until Done is set to FALSE and Auto Dispose Ref is set to TRUE. This creates a free–running, top–level VI. The front panel will not automatically display (you can set VI properties for this), nor do you want it to. Often, it is useful to initialize the front panel with localization or configuration information before showing it. The newly launched VI is responsible for closing itself. This can be signaled with the usual methods, such as queues, notifiers, and user events. It is often useful to pass a reference, such as a queue or user event to the VI before it is launched to enable this type of communication. Use the Control Value.Set method to do this. The front panel control being set does not need to be connected to the connector pane for this to work.
One caveat — if you are using the Run method to chain the operation of several VIs in an executable, you must ensure that one VI is running with its front panel open at all times. The runtime engine will terminate if no VIs are running top level with front panel open. This is a common issue with use case 2 above.
We will explore loading VIs into subpanels and why you might want to do this next time. This will be followed by posts on a splash screen use case and a localization string server. If there is any application or use case of running top–level VIs that you would like me to cover, please let me know. I will do my best to accommodate you.
08-29-2009 01:17 PM
DFGray wrote:
It is often useful to pass a reference, such as a queue or user event to the VI before it is launched to enable this type of communication. Use the Control Value.Set method to do this.
This is quite inelegant and unnatural in the data flow syntax of LabVIEW. I suggested an idea here to allow the call by reference node to run a VI without waiting for it to end, which should resolve the issue. I suggest that others that agree go there and vote for it.
Incidentally, another thing which annoys me (although I haven't checked if this still so in 8.x) is that you couldn't have the VI in memory, because the Run VI method would not execute in that case. That means you had (have?) to manually build the path and remember to include the VI in the build (or use some container to include it). An additional comment I made in that idea was that it would be nice if we could simply drag a VI into the CBR node to run it as an async VI without having to open the reference, etc.
08-30-2009 02:50 AM - edited 08-30-2009 02:52 AM
The way I usually solve the problem of passing variables to asynchronously called VIs is to use FGVs.
And I'm not really sure I like the asynchronous Call By Reference very much. For one it would show output terminals that can definitly not be used for obvious reasons. Second, when should the Call By Reference return? When the VI has started execution? When it has opened its front panel (maybe it never will do so)? It adds a lot of extra confusion and the name would have to be changed anyhow since it would be then be a Run by Reference.
But then as soon as you allow a VI to be dropped into the node it would be not by Reference anymore so the name would be misleading again. And the dropping of a VI in a synchronous Call by not-Reference would make no sense since it is equivalent to placing the subVI on the diagram, only more obscure.
Rolf Kalbermatter
08-30-2009 11:47 AM
rolfk wrote:
and the name would have to be changed anyhow since it would be then be a Run by Reference.
I think people using this feature will be able to manage that.
But then as soon as you allow a VI to be dropped into the node it would be not by Reference anymore
Correct, but it should be pointed out that this can already be done today (I don't remember the details, but I believe you can do this when setting the loading and unloading options for a VI). I personally don't have a problem with this in this case. I just want to run an async VI and pass the inputs directly.
And the dropping of a VI in a synchronous Call by not-Reference would make no sense
Again correct, which is why I added an A in front of the "sync".
08-31-2009 02:00 AM
tst wrote:
Again correct, which is why I added an A in front of the "sync".
What I tried to bring across, probably not very successfully, is that you are not talking here about a new mode of the CBR function but a new, in fact two new, functions.
You would get a Call By Reference, Run By Reference (asynchronously) and Run a VI (asynchronously).
If it would be just two new modes of the CBR there would be several problems:
- the names would be misleading in two out of the 3 useful scenarios (also in the 4th redundant case)
- the synchronous "static" call available because of symmetry reasons, would be redundant since it is the same as the VI dropped on the diagram although less intuitive
All in all maybe a useful feature in itself but a very ugly one when solved as extra modes of the CBR.
Rolf Kalbermatter
08-31-2009 07:47 AM
I have used both the FGV (Action Engine) and via a queue passed by setting the control property.
recently I have used the queue via the set method approach.
The issue with the FGV comes into play when laucnching many background VIs. I have to implement my own handshaking to enusre the loop I just luanched got the data it should use while running.
So I have been using the queues approach since I can just send of the info required to run and I can let it find it at its own pace. Yes it is sort of a break to the data flow idea but I think of that last step as a way of running the virtual wires (The queues) that can only be run at run-time.
Ben
08-31-2009 08:22 AM
This image illustrates a typicla example of how I'm doing this these days.
After a little experience using this approach, it becomes child's play.
Ben
08-31-2009 09:28 AM
rolfk wrote:
- the names would be misleading in two out of the 3 useful scenarios (also in the 4th redundant case)
Correct, although personally I don't mind either way (I think that overloading the existing node would be better than creating new ones, but I could also live with new nodes which would basically look exactly the same as the CBR). Also, I feel the distinction you make between "call" and "run" is not obvious enough and that a boolean "wait until done" input or right click option would make it much clearer.
- the synchronous "static" call available because of symmetry reasons, would be redundant
I agree, but again I will point out that this already exists today, so its redundancy is really kind of a moot point. If it didn't bother you until now, I don't see why it should bother you in the future if no one uses it (apart from the obvious reasons, which IMO don't weigh as much as the benefits).
09-01-2009 01:00 AM
tst wrote:I agree, but again I will point out that this already exists today, so its redundancy is really kind of a moot point. If it didn't bother you until now, I don't see why it should bother you in the future if no one uses it (apart from the obvious reasons, which IMO don't weigh as much as the benefits).
I'm not sure how that redundancy already exists today. You can't AFAIK drop in a VI in the CBR to be called instead of having to wire a VI reference to it. You can of course create a static reference and wire that to the CBR which is sort of similar to dropping the VI into the CBR directly but that is beside the point here, I think.
Rolf Kalbermatter
09-01-2009 03:47 AM
Question on the 1 Post:
What is the use of getting the OwningApp? I don't see it in Bens code, wouldn't be it the default behaviour? Or is it necessary when I develope Tools (running in anouther Application Instance).
Suggestions on use cases:
* Launching the same VI multiple times in parallel (clones).
* Launching VIs on a different computer (and sharing data)
Questions on Bens Code:
* Is the logger launched multiple times?
* Am I correct that you pass the VIRef via Class to the launched vit instance? So it closes the reference on it's own (but auto dispose ref is set to true)?
Felix