Scatterplot Posted November 30, 2015 Report Share Posted November 30, 2015 In looking through the CLD-R prep material, I ran across one example problem that made me realize I didn't quite understand how Events are registered/queued/whatever. See the attached image. In it, Value1 gets set to a certain value by means of a Val(Sgnl) property node. When executing this code, Value 2 will be set to the same value as the constant set to Value 1 (in other words, it gets set to 10). What I'm not understanding is the event queue mechanic. Before reviewing this and running the code, I would have assumed that the Val(sgnl) write event would have been discarded since there were no Event Queues set up at the time of the signaling event. Clearly though, the event structure Value Change event triggers once the dataflow gets to that point in the program. Do all events simply start stacking up in an event queue somewhere from the beginning of program execution? Is there an intelligent manager that only stacks up events for potential queues that may or may not happen later in the code? Similarly, if I duplicate the Event queue in that While loop (and change the Value 2 to a new variable, call it Value 3), then both queues get executed. Is there a separate event queue/stack/whatever for each event structure? Thanks for the help. If there is already a good thread on this please link me- I did some searching and didn't see anything. 1 Quote Link to comment
hooovahh Posted November 30, 2015 Report Share Posted November 30, 2015 When it comes to dynamically registered events, you are correct. If I generate a bunch of user events, then register for them, my event structure won't see the previously generated events, because it wasn't registered for them, when they were generated. Only events generated after registering will be seen and handled. It's like enqueueing elements, when the queue hasn't been initialized yet. But when it comes to static events, LabVIEW knows what it needs to register for. While I can't say for certain, I always assumed it registered for these static events, when the VI is started, before any code is executed. In actuality it might be registering for the events before the VI is even ran, but for this discussion it doesn't really matter. All that matters is static events are registered before code execution, presumably because LabVIEW can know what it needs to register for, and does it for you. When it comes to dynamic events you have more control over when to register and unregister so that isn't the case. As for your other question. Each event structure does get it's own queue to stack events onto. If you have two event structures, and they both register for the same user event (remember both register, not just register once and give that to each) then firing that one user event will be handled in both cases separately. This can be useful for a 1-N type of communication where one action is handled in N places, like a Quit event. When it comes to two event structures sharing the same static event, I think things are inconsistently handled. By that I mean if you have two event structures, handling the same boolean Value Change control, some times they both get the event, sometimes the first structure will get it and the other won't, or the sometimes the second structure gets it but not the first. Basically avoid this situation in all LabVIEW code. Because of this, and for code simplification, it is highly recommended that you only have one event structure for each VI, but that alone isn't bad for your code. EDIT: Still avoid the described situation, but as Jack said, I was confused about when this situation would happen. Quote Link to comment
Scatterplot Posted November 30, 2015 Author Report Share Posted November 30, 2015 That makes perfect sense. Thanks for the help! I've been using event structures for a while now and these situations haven't come up too often- certainly no multiple event case applications. It just hit me that I didn't really *understand* them until I saw that question come up in the CLD-R prep material. Quote Link to comment
ned Posted December 1, 2015 Report Share Posted December 1, 2015 Note that this also means that if you place an event structure inside some other structure - for example, in a case structure - then events will stack up in the queue for that event structure even if there's no possibility of it running. Coupled with the option to lock the front panel until event processing completes, this can (and often does - see the NI forums) cause a lot of confusion, because the user clicks a button and the front panel freezes but since the event never processes, the front panel never gets freed. Quote Link to comment
hooovahh Posted December 1, 2015 Report Share Posted December 1, 2015 Coupled with the option to lock the front panel until event processing completes, this can (and often does - see the NI forums) cause a lot of confusion, because the user clicks a button and the front panel freezes but since the event never processes, the front panel never gets freed. Yeah I suspect new users think of an event structure as a type of interrupt, or goto function, and when dataflow is the name of the game, that just isn't the case. Quote Link to comment
Scatterplot Posted December 1, 2015 Author Report Share Posted December 1, 2015 Note that this also means that if you place an event structure inside some other structure - for example, in a case structure - then events will stack up in the queue for that event structure even if there's no possibility of it running. Coupled with the option to lock the front panel until event processing completes, this can (and often does - see the NI forums) cause a lot of confusion, because the user clicks a button and the front panel freezes but since the event never processes, the front panel never gets freed. Interesting- so does the "lock during processing" start when the event is triggered, or when the event case dequeues the event from its stack? Quote Link to comment
hooovahh Posted December 1, 2015 Report Share Posted December 1, 2015 I never really messed with this feature much, so I had to write some test code to see. It appears the locking of the FP occurs on static events when the event occurs, not when it is dequeued. Same goes for dynamic control references, if the register has the "Lock Panel Until Handler Completes" by right clicking the register for events. As for user events, it appears this isn't an option because user events don't involve UI controls. 1 Quote Link to comment
Scatterplot Posted December 1, 2015 Author Report Share Posted December 1, 2015 I never really messed with this feature much, so I had to write some test code to see. It appears the locking of the FP occurs on static events when the event occurs, not when it is dequeued. Same goes for dynamic control references, if the register has the "Lock Panel Until Handler Completes" by right clicking the register for events. As for user events, it appears this isn't an option because user events don't involve UI controls. Awesome, thanks for checking into that Quote Link to comment
JackDunaway Posted December 2, 2015 Report Share Posted December 2, 2015 When it comes to two event structures sharing the same static event, I think things are inconsistently handled. By that I mean if you have two event structures, handling the same boolean Value Change control, some times they both get the event, sometimes the first structure will get it and the other won't, or the sometimes the second structure gets it but not the first. Basically avoid this situation in all LabVIEW code. This one bit is not quite correct. You're thinking about multiple Event Handler Structures binding to a shared queue created by a single Register For Events Node. That's the scenario that produces undefined behavior. (Not just unpredictable behavior; truly undefined behavior) Multiple Event Handler Structures bound to a "Statically-Registered Event" are OK, but as hooovahh suggests, not usually recommended. --- "Statically-Registered Event" -- contrasted with "Dynamically-Registered Event" -- is just a silly terminology for "magic wires that you don't see that you just 'know' must exist". The original post is an excellent case study for the mental leap required to learn/believe/trust/understand Static Event Registration. For some reason, in LV world it's taught that Static Event Registration is "easier" than the "advanced" topic of Dynamic Event Registration. Maybe if Dynamic Event Registration were taught like this -- it's wires you see, in the code you wrote, that code in front of you on the block diagram; that's what happens and why it happens. And lifetimes of both the event sources and event sinks -- yeah, that's kinda just wires too -- the wires you see in front of you, on the code you wrote. Understand this, and then the concept of "Static Event Registration" might help you by replacing a little syntax with some accepted, implicit convention. Said another way -- Dynamic Event Registration is syntax where the mental model maps to the visual source model, whereas Static Event Registration is just a shortcut that hides implementation details. (Yes, there do exist some notable functional differences between the two, but that's just a shortcoming of both, not a fundamental difference in the model) @Scatterplot -- as an excercise, can you create the same diagram, just with a static reference to `Value 1`, wired into a `Register for Events`, wired into the Event Handler Structure? Post that snippet, then let's use that as an explicit example to the "wireless" model of Static Event Registration. 1 Quote Link to comment
hooovahh Posted December 2, 2015 Report Share Posted December 2, 2015 This one bit is not quite correct. You're thinking about multiple Event Handler Structures binding to a shared queue created by a single Register For Events Node. That's the scenario that produces undefined behavior. (Not just unpredictable behavior; truly undefined behavior) Thank you very much for the correction, I've edited my previous post. For answering several questions in this thread I went and wrote code to confirm my assumptions. When it came to answering that question I just assumed I knew what it would do but as you mentioned gave the right answer to a different question. Quote Link to comment
mje Posted December 3, 2015 Report Share Posted December 3, 2015 While I can't say for certain, I always assumed it registered for these static events, when the VI is started, before any code is executed. In actuality it might be registering for the events before the VI is even ran, but for this discussion it doesn't really matter. It definitely happens before code execution. I can't say with certainty exactly when it happens either (and indeed it's academic to this discussion) but if you peer down into the bowls of xcontrols, recall there's an event structure in there that magically gets signaled from a VI that isn't running. Something tells me that this registration is happening when the VI gets reserved, and execution/starting doesn't have anything to do with it. Quote Link to comment
hooovahh Posted December 3, 2015 Report Share Posted December 3, 2015 but if you peer down into the bowls of xcontrols, Oh that reminds me, XControls have some kind of limitation when it comes to using user events, I believe you can't use user events at all, that are created from outside the XControl, and I wonder if when it executes and registers has something to do with this limitation. Quote Link to comment
Popular Post Yair Posted December 6, 2015 Popular Post Report Share Posted December 6, 2015 Something tells me that this registration is happening when the VI gets reserved, and execution/starting doesn't have anything to do with it. Correct, although this isn't actually relevant for XControls, as they do actually run even if the VI is not running. Another term for "reserved" would be "entering run mode" and it happens when the hierarchy the VI is in starts executing and the run arrow changes from white to something else which isn't broken or unsynced. Here's a table I did a while back and never got to use: It doesn't include all the states (like the green arrows), but it is fairly representative. The relevant states are the bottom three. This behavior can actually have consequences if you have weird code like setting val(sgnl) from another VI or if you register for an Application event like VI Activation and it's certainly relevant if your user manages to do something like double click on controls before the VI closes, as the events are saved in the queue even if the VI isn't running and will be processed the next time the VI is called and the event structure executes. 3 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.