02-10-2017 05:20 PM - edited 02-10-2017 05:22 PM
I know you should always close references when possible. However, I inherited some code that is closing .NET references with a local variable. I created this example from the NI Calling a Privae .NET Assembly.vi to simplify my question. The top diagram is the "proper way". The bottom diagram is what I see in the code. IN the bottom diagram the Calc reference is a hidden indicator. Will this work? Same question goes for Callback references and other non .NET objects. Remember this example is quite simplified. My basic question is will closing a reference using a local variable to that reference actually close the reference?
Solved! Go to Solution.
02-10-2017 05:58 PM
@EduNI wrote:
My basic question is will closing a reference using a local variable to that reference actually close the reference?
Only if the local variable is read AFTER the terminal is written, which it probably isn't in the example you give.
02-10-2017 06:00 PM
Technically, it should still work.
02-10-2017 06:17 PM
@drjdpowell wrote:
Only if the local variable is read AFTER the terminal is written, which it probably isn't in the example you give.
The issue is when you CLOSE it, not when you READ it. Since it's a reference, it doesn't matter when you read the value.
02-10-2017 11:08 PM - edited 02-10-2017 11:11 PM
@nathand wrote:
@drjdpowell wrote:
Only if the local variable is read AFTER the terminal is written, which it probably isn't in the example you give.
The issue is when you CLOSE it, not when you READ it. Since it's a reference, it doesn't matter when you read the value.
I disagree.
The Calc Reference indicator holds the value of the calculator reference. If the local variable of the reference indicator is read BEFORE the value of the reference is written to that indicator, It is a classic race condition. If the local variable executes first, it will have 0, or null, or whatever is the default value of an non-existent reference. Then the calculation node executes and the reference value of that then gets written to CalcReference indicator. Next the case structure executes and the invoke node will run with the valid reference on the wire. Then the case structure ends and the Close function executes, but it will execute on the reference valid that comes from the local variable, but that is probably 0 or an invalid reference because it was read before the reference's value was passed to it.
Someone test it. If it happens to work, then maybe you got lucky with the race condition. Try it with highlight execution. And try it where you force the local variable to be read before the reference is written to the indicator.
02-13-2017 08:40 AM - edited 02-13-2017 08:53 AM
Thanks for the excellent feedback. I'm guessing it is the same situation for a reference to the front panel control as it is for a local variable - that it could lead to a race condition depending on when it is read? Other than the possible race condition, (assume you could assure no race condition) is it better to use the reference to front panel vs the local variable for this purpose?
It is clear that one should always explicitly close a reference to a .NET object created with a Constructor Node. Is it the same for object references created with an Invoke node, i.e. is it required or recommended to close a reference to an object created by an invoke node? In the example below, a device reference is create with a .NET Constructor node (not shown) passed to the Device Open Invoke Node, followed by an Invoke Node which creates a ClientConnection reference using the previous device reference. It is clear I should explicitly close the device reference, however, since the ClientConnection is "derived" (I'm sure not the right term) from the device reference, is there a need to also close the ClientConnection reference?
02-13-2017 08:45 AM
I am siding wth RavensFan on this one.
LV will often schedule work that has no datata dependancies to happen up-front. In the code shown the read from the local is one of those sitatuions. So it CAN be read before it is writen.
Re: Closing...
SImple answer is "depends". Cat your ref number as an I32 and display same. If the number changes each time the code is run, it should be closed.
Ben
02-13-2017 11:12 AM - edited 02-13-2017 11:13 AM
@EduNI wrote:
Thanks for the excellent feedback. I'm guessing it is the same situation for a reference to the front panel control as it is for a local variable - that it could lead to a race condition depending on when it is read?
In almost all situations you don't need to close control references. If you explicitly opened them, then yes they need to be closed but this generally only happens when you are writing scripting code. Closing a control reference, or VI reference that can't be closed will operate like a no-op. Here is an article talking about when to close references. And a LAVA discussion on the article.
Unofficial Forum Rules and Guidelines
Get going with G! - LabVIEW Wiki.
17 Part Blog on Automotive CAN bus. - Hooovahh - LabVIEW Overlord
02-13-2017 12:03 PM
@RavensFan wrote:
@nathand wrote:
@drjdpowell wrote:
Only if the local variable is read AFTER the terminal is written, which it probably isn't in the example you give.
The issue is when you CLOSE it, not when you READ it. Since it's a reference, it doesn't matter when you read the value.
I disagree.
Yes, you're of course correct. I didn't read the initial statement carefully and interpreted it to mean after the invoke node was called, where you clearly wrote "terminal" referring to the terminal associated with the local variable.
02-13-2017 01:08 PM
A Local (or Global) variable to a reference just sounds like a really bad idea. If you really need to avoid the wire an Action Engine with Open / Get / Close methods sounds a whole lot safer and a darn sight easier to debug.