02-03-2015 08:11 AM - edited 02-03-2015 08:29 AM
I have a strange problem with values returned by "wait on asynchronous call".
In the attached png you can see the section of code that calls a VI as a separate
thread and waits for the user to make a selection from a list of available devices.
The VI being called is the one pointed to by the strict reference (the icon with the
red star on top of it).
(image edited after Bob_Schor suggestion, thank you)
I have verified that the VI is actually called, that it executes correctly, and that the
object that it must return, connected to the topmost terminal on the right (the
yellow terminal in the collecting VI) has been properly initialised (e.g., I can
query it to return its current state, and the query is the last action executed on
the wire that then feeds into the output indicator).
However, if I try to query the object that is returned by the collecting VI, it is
corrupted (e.g., the VISA reference inside it has been erased or reinitialised,
not always in the same way), and the same query that would work as the last
action of the external VI fails as first action on the outgoing yellow wire.
I don't know if this may help, but the calling VI and the called VI are part of two
different libraries in two different LabVIEW projects. I am saying this because
I have already tried this technique within a single project, and it works fine.
Can you spot any improper way of handling the inter-VI communication in the
previous image?
Thanks in advance,
Stefano B.
02-03-2015 08:24 AM
My eyesight isn't good enough to see the above image clearly. Do you know about "Snippets"? If you open your VI, select this code, and from the Edit menu choose "Create VI Snippet from Selection", you'll create what looks like a PNG file, but when you do an "Insert Image" into your post, we'll be able to drag this image into a blank VI and have it "magically" become LabVIEW code (we can, in principle, even execute it!).
Once we (maybe I should say "I") see more clearly what you are trying to do, we (?I?) could give a more helpful answer.
For what it is worth, I've used Asyncronous Call and Collect, and it seems to work. I don't quite "get" the distinction you made about two different Projects, but maybe it will become more obvious with better "vision".
BS
02-03-2015 08:39 AM
I think this is expected behaviour. When you get the result from the asynchronous call you then close the reference to the VI - I think that will mean any references within the VI will become invalid (e.g. automatically closed when the VI reference is closed/leaves memory).
I think you can either:
- Not close the VI reference until you've finished with the references
- Possibly feed in a DVR so the reference in maintained outside of the asynchronously called VI?! (I'm not 100% certain as this is nearing the limit of my knowledge of the lifetimes of references etc.)
02-05-2015 03:43 AM
I have an update after further application debugging.
I have found and corrected some trivial errors that were obfuscating the picture.
Forget about my statement on different projects, that note is actually irrelevant.
The problem is that the asynchronously called selection routine generates
(i.e., creates, then initialises) an object that contains a VISA resource. When
the call returns and the result is collected I have my object, and it still contains
the VISA resource, but the resource itself has been reinitialised (or gets
reinitialised the first time I use it) (in particular, the termination character has
been reinitialised, which leads to communication breakdown).
As Sam_Sharp pointed out, this is probably due to the initial VISA session being
destroyed when the asynchronous call returns and that VI stops running (since
its call is asynchronous, it is treated as a top-level VI, and the VISA reference
created inside it is deleted when it stops -- if instead you call it as a subVI the
VISA reference scope seems to be linked to its topmost VI, i.e., my application).
I will now investigate whether the VISA session lifetime can be extended beyond
the selection VI by using data-value references (DVRs).
Curiously, my object also contains a reference to a queue, and it works fine,
as if queues' scope was different (linked to the VI server or something else,
they seem to be global). Do you have any idea about the reason of this different
behaviour?
02-05-2015 04:39 AM
Sorry, still a wrong assumption on my side.
The queue reference was invalidated too.
I can prevent the VISA resource invalidation by unchecking
"Automatically close VISA sessions" in Tools -> Options -> Environment
but it is a general fact that if I store references into my object,
as I intend to do plentiful, they do not survive returning from
an asynchronous call where the object was created.
02-05-2015 05:51 AM
Yes, that is correct. Once a VI leaves memory (reference is closed) it usually cleans up references - if you have a 'release queue' VI that is the last open reference to the queue, then the queue will be destroyed. This means if you use named queues by opening / enqueuing / closing the queue reference - if that reference isn't also open somewhere else (e.g. by the de-queuer) then nothing will get enqueued and you won't get any error unless you have the 'create if not found' set to false.
You would either need to keep the VI in memory for the whole execution so the reference stays valid or make sure the reference is created on your top-level VI - I normally do this by having an initialise VI that creates the queue references, a 'server' or 'daemon' VI which stays running in the background and then a shutdown VI which tells the server to shutdown and releases the queue references.