Jump to content

Generate occurrence in FOR loop returns same reference


Recommended Posts

Wow while troubleshooting some code I noticed that calling the "Generate occurrence" function always returns the same reference if used in a loop or in a SubVI that you call several times. The only way to get different references is to physically place several instances of it on the BD.

 

Is that the expected behavior? And in a more general way, what do you think of occurrences? I like them because they are so light and simple. I use them when I only have one "sender" and one "consumer" and that I don't need to pass any data...

 

Edit: A glance at the LabVIEW Help indicated that indeed this is the normal behavior. I'm still interested in knowing what are your thoughts on occurrences...

Edited by Manudelavega
Link to comment

I believe this is by design. Occurrences are slightly different to other kinds of reference (like notifiers etc) and the actual occurrence reference is determined at compile time or something like that.

 

I remember reading something about this on ni.com years ago. Will try and dig it up.

Link to comment

I have seen a VI which actually destroys an occurrence.  It's certainly not supported and I don't think it's included in a LV install either.

 

I think it allowed a piece of code which was waiting on an occurrence with timeout "-1" to exit with a timeout flag set to TRUE, giving the loop an exit strategy.  But I never actually used it so don't quote me on that.

Link to comment

Wow while troubleshooting some code I noticed that calling the "Generate occurrence" function always returns the same reference if used in a loop or in a SubVI that you call several times. The only way to get different references is to physically place several instances of it on the BD.

 

Is that the expected behavior? And in a more general way, what do you think of occurrences? I like them because they are so light and simple. I use them when I only have one "sender" and one "consumer" and that I don't need to pass any data...

 

Edit: A glance at the LabVIEW Help indicated that indeed this is the normal behavior. I'm still interested in knowing what are your thoughts on occurrences...

 

The Create Occurrence node only executes at VI load time and that is by design. It has been that way since the inception of occurrences in LabVIEW back around LabVIEW 2.0. There is the undocumented LabVIEW manager function AllocOccur() that returns a unique occurrence refnum every time it is executed. However since around LabvIEW 6 you have notifiers, queues, and semaphores which internally do use occurrences for the signaling aspect but have extra advantages of allowing to transport some data along with the signal event that occurrences don't have.

 

Occurrences did have a nasty feature in the past and may still have that could bite you if you are not careful. Their state would remain triggered once they were set if the Wait on Occurrence wasn't executed before the program was terminated and would immediately trigger the Wait on Occurrence on a new start of the application even if in this new run the occurrence hadn't yet been set.

 

As to destroying the occurrence to let the Wait on Occurrence terminate, that sounds like a pretty brute force approach. Why resolve to that instead of just setting the occurrence anyways?

Link to comment

Edit: A glance at the LabVIEW Help indicated that indeed this is the normal behavior. I'm still interested in knowing what are your thoughts on occurrences...

 

I only looked at occurrences for a very brief while. At the time, I thought that its design is inconsistent with other mechanisms in LabVIEW, so I decided not to use it.

 

See this article: Why Am I Encouraged to Use Notifiers Instead of Occurrences?

Link to comment

Destroying an Occurrence:

 

The logic goes like this: You wire up a "Wait on Occurrence" with a Timeout of -1.  This controls the loop execution.  No polling due to timeouts.

 

When do we exit this loop?  With Queues and Notifiers we can destroy the reference and use this to let the listening processes know that the communications channel has been closed.  With Occurrences you can't do this unless you destroy the occurrence.

 

There is no error out for an occurrence, therefore a Timeoue = TRUE for an Occurrence set to wait forever becomes a Quit condition.

 

I'm not condoning the usage (I'd be closer to condemning it), I have never used it and would never choose it over other methods.  But apparently there were times where existing code needed modification for such a quit method and this was the solution.


Just to add another 2c.  I'm actively REMOVING occurrences from our software whenever I need to refactor something.  Not that anyone thinks I'm a weird Occurrence fetishist or anything.

Link to comment

Destroying an Occurrence:

 

The logic goes like this: You wire up a "Wait on Occurrence" with a Timeout of -1.  This controls the loop execution.  No polling due to timeouts.

 

When do we exit this loop?  With Queues and Notifiers we can destroy the reference and use this to let the listening processes know that the communications channel has been closed.  With Occurrences you can't do this unless you destroy the occurrence.

 

There is no error out for an occurrence, therefore a Timeoue = TRUE for an Occurrence set to wait forever becomes a Quit condition.

 

I'm not condoning the usage (I'd be closer to condemning it), I have never used it and would never choose it over other methods.  But apparently there were times where existing code needed modification for such a quit method and this was the solution.

Just to add another 2c.  I'm actively REMOVING occurrences from our software whenever I need to refactor something.  Not that anyone thinks I'm a weird Occurrence fetishist or anything.

 

I thought it would be this but that has many shortcomings. The only way to destroy an occurrence is by calling the DestroyOccur() C API in LabVIEW. However if you do that with an occurrence that was created with the Create Occurrence node that occurrence is gone and the only way to get it back is by unloading and reloading the VI that contains the Create Occurence node. Without reloading the VI, this occurrence will be invalid and immediately run into the timeout case again if you restart the VI. Not exactly a convinient thing when you are developing and starting and stopping your app repeatedly.

 

Of course if you create the occurrence by calling the AllocOccur() API this is not an issue but then you call already two undocumented C APIs.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.