LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

What does "refnum not valid in this context" mean andwhat are the ground rules for when a queue refernce is valid or not?

Solved!
Go to solution

Ben wrote:

Not in 2009!


Woohoo!

0 Kudos
Message 41 of 47
(1,779 Views)

Ben,

 

You are not alone...  I ran across a similar issue using Notifiers.  Hence I revived the thread.  Many thanks to Yair for linking me to this thread.  Lots of brilliant minds in these forums.

 

I am quoting below because I need to get back to this... But I need to finish reading everything and try to digest the info.. 

My situation is different..  At least I think it is..  I probably will reply with more details tomorrow.  It's been a long day / week / month...

 

I started a discussion on LAVA that I will probably continue in this thread (if Ben doesn't mind).

http://lavag.org/topic/16393-refnum-for-a-notifier-reference-object-not-valid-in-this-application-in...

 

 

EDITE:  Plus reminding myself to go back and look at this post: http://forums.ni.com/t5/LabVIEW/What-does-quot-refnum-not-valid-in-this-context-quot-mean/m-p/105232...

 


@AristosQueue (NI) wrote:

Ben wrote:

Thank you Aristos Queue!

 

I am very sorry you had to be the one to reply to this thread since I was trying get an answer without bugging you.

 


It's ok. This is my area of expertise (thus my user name), so it makes sense that I end up getting this question. The queue and notifier primitives were the first feature I wrote for LV back in LV6.1 and I've maintained them ever since. 

 

And with that... on to the rest of the questions:

 

@Ben wrote:
What code/project context foreces/uses multiple context?

 

Application instances (sometimes accidentally called "contexts" by R&D folks) are islolated instances of LabVIEW. Prior to LabVIEW 8.0, this meant a separate labview.exe or built application using lvrt.dll. Nowadays, we can have multiple application instances within the same labview.exe or built application. These separate app instances are boxes: the VIs inside one box do not know about and cannot directly interact with the VIs in another box. The only ways to communicate between two different boxes are the same features of LabVIEW that allow communication with another physical machine. Among these features are the Open App Instance primitive, the TCP/IP primitives and the Network Shared Variable. There are others. Generally, a feature can be used for communication between app instances if and only if it takes a port number or URL as part of its setup. Queues, notifiers, data value references, and file refnums (to name a few) do not, so you know they are only for communication within the context. 

 

@Ben wrote:
What I am looking for ideally is a white paper that has not been written yet that describes each of the process contexts that we should expect our code to run in and when and under what circumstances these contexts are used.
 

If you open VIs without opening a project (.lvproj file), those VIs open in the "main LabVIEW app instance" or "default app instance".

 

If you open a project, the VIs under "My Computer" in that project will all be in their own app instance. Thus if you have two projects open, the VIs in each project are isolated from each other. That's how you can have two VIs of exactly the same name in memory simultaneously -- if each one is in a different project, they are in separate app instances.

 

A project can have multiple targets (FPGA, RT, PDA, etc). Each target is a separate app instance.

 

AND THAT'S IT. There are other private app instances created inside the LV editor -- isolated boxes where LV runs VIs that are part of LV itself. For example, a lot of the Project Window's functionality is written in G, but if you ask for "All VIs In Memory", you won't see all the VIs that are part of the project... those VIs run in an isolated app instance, and the "All VIs In Memory" method returns the VIs only for the calling app instance. 

 

To the absolute best of my knowledge, no user feature other than the project automatically creates separate application instances for user-written VIs to run. There is a method that exists (and I *think* it is public for users to invoke) that can deliberately create a new app instance, but if you're not invoking that explicitly, then the app instance in which your VIs run should *always* be the app instance it is loaded in (i.e., the project app instance or default app instance).

 

Which raises the question: why is Ben seeing this error? I have no idea at this time. 

 

@DFGray wrote:
Contexts are generally used by the LabVIEW team to hide running LabVIEW code so it is not an annoyance.  For example, the FPGA Wizard, a LabVIEW application, runs in a separate context to prevent its hundreds of VIs from showing up in the VI hierarchy, causing more than a minor annoyance.  LabVIEW has several standard contexts for this purpose.

 

Project and target isolation are the other use cases for app instances. LabVIEW also creates temporary app instances for actions such as Build Application, where we may load a copy of user VIs in order to modify them (operations such as "disconnect typedefs") before building them into the EXE. The isolation of the boxes keeps us from modifying the original user VIs in the project app instance.

 

@Robbob wrote:
NI does not recommend typecasting references unless you are very familiar with the underlying data, as it is easy to make mistakes.

 

In general, LabVIEW should never crash if LV R&D has done its job right. There are  two exceptions to this rule: your VI is calling out to a third-party piece of code that does something to cause a crash OR user uses Type Cast to cast one refnum into another type of refnum. Sometimes this works, sometimes it doesn't. The typecasting on refnums is intended to allow you to cast a refnum as an integer to use as a lookup key and then cast back to the same type of refnum when you're done using it. Unfortunately, you can cast them directly, and LV may or may not work right when you do this.

 

So when Robbob says "NI does not recommend typecasting references", I'd interpret this as "Use typecast to cast references to int32 and cast back to same refnum type, but never do anything else unless explicitly told 'this is safe' by someone who can see and understand the under-the-hood code of LabVIEW."

 


More in a little while... I'm putting together images for queues/typedefs/coercion dots.

 




0 Kudos
Message 42 of 47
(1,518 Views)

@AristosQueue (NI) wrote:

@Robbob wrote: I didn't think of the case where you would want to use a lookup key, very interesting. I just know in the past when typecasting refnums and running into issues, I was generally told 'Don't do that'

Excellent advice. Pass it along to the next newbie. If that newbie someday needs casting, he or she will ask and someone will tell them about it at that point. Most LV users never do.


You ARE talking about NOT Typecasting refnums..  But it is OK to TypeDef refnums from Notifiers.  Or are both a No- NO!

I'm still reading.  I don't want to forget any of the details along the way..

 

Just trying to understand what's going on / what happened / why it happened, etc.

 

Ben.Jr

0 Kudos
Message 43 of 47
(1,514 Views)

@tst wrote:

Aristos Queue wrote:

 

I would've guessed LV 6.1, but you've made me doubt myself, so we'll go with 8.0 for now. 

...


I think what I'm thinking about is that if you created a queue reference indicator from the obtain queue primitive in earlier versions it did NOT automatically link to the typedef. You had to either make the reference a typedef as well or know the trick of dragging the data type into the reference (which you have to admit is not something most users know).


I'm not sure what part isn't documented. You can drag any type onto the queue control/indicator to set the type of the queue's data, including typedefs.

... 

 

I don't see anything wrong with not typedef'ing the queue


Niether do I. It's much better.

 

BUT. It's much better IF and ONLY IF it's guaranteed that every instance of that reference will update correctly when I update the typedef today and in future versions. I'm pretty sure that's not documented and from a user's perspective, what's not documented is subject to disappear (even if the great AQ declare this "officially recommended practice").

 

Which isn't to say I don't do this. I never typedef my queue and notifier refs. I do rely on this behavior because I do see it as a feature. It's just that as long as it's not officially clear that it's there to stay, I am technically doing something which is against the standard best practice.


 

Oh boy... Have I stumbled on the root cause for a performance issue that I reported in another thread?  Would creating hundreds of TypeDef'ed Notifier references cause LabVIEW to have constipation?  (not sure how else to describe it using few words)

 

So what would be the proper "standard best practice"?  I will need to put this into context by showing code and how the code is created, etc...

0 Kudos
Message 44 of 47
(1,512 Views)

Post deleted... clicked twice on post button

 

I may as well use this wasted post to mention that the code was developped using LabVIEW 2010.  It is now going to 2012. 

0 Kudos
Message 45 of 47
(1,512 Views)

Ray.R wrote:

Oh boy... Have I stumbled on the root cause for a performance issue that I reported in another thread?  Would creating hundreds of TypeDef'ed Notifier references cause LabVIEW to have constipation?  (not sure how else to describe it using few words)


Typedefing notifers (or queues or events or any other refnum) is not a performance issue. Typedefs have very little runtime impact. The reason not to do it is that it provides very little benefit at edit time if the underlying type is already a typedef, and if the underlying type is not a typedef, you really have to ask yourself, "If I'm bothering to typedef the queue/notifier, why *isn't* the underlying type a typedef?" After all, you probably are not going to change a queue into a notifier, so the real point of creating a typedef of the queue or notifier is to let you easily change the type of the thing inside the queue or notifier. But that inner type is used indepdendently all over the diagram before it is enqueued and after it is dequeued. So if you expect the core type to change, you should be making the inner type a typedef.

 

To be clear: it is not a no-no, it's just useless, IMHO.

0 Kudos
Message 46 of 47
(1,486 Views)

It's good to be away from a thread... come back and read the last portion again.  The notifier is not a typeDef.  The control which is going to the notifer is.  I am preparing a document that describes how I prepare the objects within the LabVIEW class and how the private & public members are created.  I will discuss it in a new thread.

The "refnum not valid in this context" is an intriguing issue, which has not re-surfaced. (not yet)

0 Kudos
Message 47 of 47
(1,450 Views)