Jump to content

Intending to Use Event Structures to Manage "Pop Up" UIs, any warnings?


AlexA

Recommended Posts

Hi guys,

I'm playing around with the idea of using event structures in asynchronous sub vis which take an event registration refnum as a terminal. These sub vis will handle UI associated with specific tasks, say, controlling a motor. Buttons pressed in the sub-vi will passed to my main controller via queues. Information arriving to the main controller will be sent to the relevant sub-vi by generating the appropriate user event.

Are there any caveats I should be aware of?

-Speed limitations?

-Data limitations? (i.e. is it ok for me to pass something like a 512kb bitmap image via a dynamic event)

I'm already aware of the minor annoyance involved in updating a dynamic event refnum. i.e. having to update a typedef for every modification.

Thanks in advance for your insights,

Alex

Link to comment

Can't think of any problems with what you have listed, but there are a couple that I can think of in terms of cons vs queues..

Cannot use them for subpanels (well, you can, but your events won't work).

Cannot guarantee execution order (might not be a consideration for you).

Cannot easily encapsulate (for the reason you mentioned about typdefs).

Edited by ShaunR
Link to comment

I've implemented a similar structure with a waveform viewing application. There were multiple user-selectable user interfaces that all used a single action loop to do the work. I passed a DVR to the UI on initialization containing the data and then sent an event back to the UI that the data had been updated inside the DVR. I did a test where 10,000 waveforms of 4096 points were loaded and displayed, and did not see a performance issue (the graph does slow down at that point).

Link to comment

The event structure. Events are handled in the owning vi.

I may not understand the architecture in question. As I understand it, if you have a subVI Front Panel in a subpanel of the main VI, then clicks on that (sub)Front Panel trigger events in the subVI’s event structure. And Alex is going to communicate this to the main VI via a queue, with the main VI talking back via a User Event. Should all work fine.

Link to comment

The event structure. Events are handled in the owning vi.

Not sure what you mean here about events not working in subpanels - I've got more than one project that uses subpanels and and the subpanel will handle most any front panel event (save for the keydown event - that one always gets handled by the calling VI) and any user-defined event I've tried.

As far as AlexA's question, I've found it easier to just expose the events and let the subvi's handle registration rather than using the event registration refnum.

Link to comment

I may not understand the architecture in question. As I understand it, if you have a subVI Front Panel in a subpanel of the main VI, then clicks on that (sub)Front Panel trigger events in the subVI’s event structure. And Alex is going to communicate this to the main VI via a queue, with the main VI talking back via a User Event. Should all work fine.

Yeah. I wasn't very clear in pointing out the caveats (and wasn't worded very well either-been up for 36 hrs already. I shouldn't really post).

using_events_and_subpanels

Edited by ShaunR
Link to comment

Thanks for the info guys, just to get it really explicit, does anyone know what the overhead is like with using an event to send data? As I mentioned in the OP, say I want to display a 512kb image (1024x512px, greyscale) in a sub-vi, at a rate of 40Hz, how would this compare to sending that information by queue, or just viewing the data in a graph in the main message handler when it arrives (rather than sending to a sub-vi).

Link to comment

Thanks for the info guys, just to get it really explicit, does anyone know what the overhead is like with using an event to send data? As I mentioned in the OP, say I want to display a 512kb image (1024x512px, greyscale) in a sub-vi, at a rate of 40Hz, how would this compare to sending that information by queue, or just viewing the data in a graph in the main message handler when it arrives (rather than sending to a sub-vi).

I don't think your limiting factor will be passing the data whether you use queues or events - the most resource intensive activity will be the graph display front panel updates no matter if they occur in the main message handler or a sub-vi.

Edit - one issue you may run into passing the data thru a queue or event to a sub-vi is making inadvertent copies of the data that would not happen if you display in the main VI. Just something to watch out for.

Link to comment

I'm playing around with the idea of using event structures in asynchronous sub vis which take an event registration refnum as a terminal.

My only recommendation is to never do this. Event registration refnums are strictly typed and can't be changed easily as you implied. It might seem like a minor inconvenience now, but you can really end up in a bad situation if you start passing those registration refnums all over the place.

Plus, why would you want to pass an event registration refnum around? There should be a one-to-one relationship between event structures and registration refnums. Make a typedef cluster of your events refnums, pass those into a subvi, then obtain a registration refnum from the cluster in the same VI you need it.

Link to comment

Plus, why would you want to pass an event registration refnum around? There should be a one-to-one relationship between event structures and registration refnums. Make a typedef cluster of your events refnums, pass those into a subvi, then obtain a registration refnum from the cluster in the same VI you need it.

This is the way to go. The only issue to be aware of, is that you shouldn't generate an event in a subVI, for another parallel running subVI, until it has registered for the event. If you do generate the event before it is registered the event will be lost.

You may want to implement some kind of hand shaking mechanism to ensure that a event is not fired, until it has been registered.

Link to comment

I use events extensively in my projects and I often times have multiple subVIs registered for the same user event with no issues. Something to be aware of is that registering for an event creates a queue to hold the event data until you can process it. You have no control over that queue and if you ever can't process the data fast enough, it can back up until your program runs out of memory. This can be an issue with large data types in user events. With a queue, you can set limits on the size and handle overflows yourself. I like to make a Boolean or integer "flagging" event with another object to hold the actual data. Depending on what your requirements are, Data Value References can work great, especially if you can normally respond to events fast enough and are okay with possibly missing samples if the DVR updates again before you get to it. Plus if you use a standard data type for your flagging event, you can change your data object without having to retype your event reference terminals.

I have also run into issues with high numbers of events slowing down even when the computer was not experiencing high CPU load. In one test, I was attempting to generate 5000 events at a rate of 20Hz, but the events were only being generated at about 15Hz and the CPU was only at about 10% utilization. I think it was an issue with the Windows event service. Because of that, I modified those data classes to only generate their events when something subscribes to them. Otherwise they update a buffer that I can read at sparser intervals.

Link to comment

The event structure. Events are handled in the owning vi.

Yeah, that's been int he LV help for years but to the best of my knowledge it's either simply wrong or hugely misleading. I work a lot with events and with subpanels and I've never encountered a problem. I hesitated for a long time because of this text in the LV help. I never understood what it meant.

Shane.

Link to comment
Yeah, that's been int he LV help for years but to the best of my knowledge it's either simply wrong or hugely misleading. I work a lot with events and with subpanels and I've never encountered a problem. I hesitated for a long time because of this text in the LV help. I never understood what it meant.

I’m guessing this refers to a very limited list of events that could meaningfully belong to either VI, like “This VI>>Key down”, rather than the vast majority of events, like on controls, that only one VI can register for.

Link to comment

I'm playing around with the idea of using event structures in asynchronous sub vis which take an event registration refnum as a terminal.

My only recommendation is to never do this. Event registration refnums are strictly typed and can't be changed easily as you implied. It might seem like a minor inconvenience now, but you can really end up in a bad situation if you start passing those registration refnums all over the place.

Plus, why would you want to pass an event registration refnum around? There should be a one-to-one relationship between event structures and registration refnums. Make a typedef cluster of your events refnums, pass those into a subvi, then obtain a registration refnum from the cluster in the same VI you need it.

There's a valid reason to pass an event registration into a SubVI to be SubPanelled, and that's when you want to "pre-stuff" the mailbox with some events prior to the SubVI running. This is because the "Register for Events" node is unaware of User Events that have been sent along a User Event Refnum -- which incidentally demonstrates the beauty and power of separating the messenger (User Event Ref) from the mailbox (Event Registration Refnum).

Yes, I agree it's a pain if you change the datatype of the message; or if you want to rename the case label on the Event Handler Structure. :(Coerce to Type ostensibly handles the second problem; the first problem is solved by convention (don't change your mind on datatype! :lol: ).

Link to comment

There's a valid reason to pass an event registration into a SubVI to be SubPanelled, and that's when you want to "pre-stuff" the mailbox with some events prior to the SubVI running. This is because the "Register for Events" node is unaware of User Events that have been sent along a User Event Refnum -- which incidentally demonstrates the beauty and power of separating the messenger (User Event Ref) from the mailbox (Event Registration Refnum).

If you stuff the event registration with events and then wire that event registration to more than one event handler (as one might, in a publish-suscribe tye design), how do you ever know which event structure will handle which event? It has been my empirical observation that you can end up with a scenario where 1) you load events into your event registration ref (mailbox) 2) you wire that node to more than one dynamic event terminal 3) One event structure registers first and goes and empties the mailbox (event registration) before the other event loop gets a chance to check. As far as I can tell, this happens because the event queue has only one registered listener when the events are consumed so it discards the events as soon as the first event structure consumes them. Or, I have even observed behavior where it appears the second event handler gets there somewhere in the middle of emptying the mailbox and gets some but not all of the events that were registered.

I got nervous enough about this sort of thing that I stopped exposing event registration refs and just expose event refs in my designs. It can't handle the scenario you described, but I don't trust using events that way in a publish-suscribe type architecture where there are likely to be multiple listeners for any event.

Link to comment

If you stuff the event registration with events and then wire that event registration to more than one event handler (as one might, in a publish-suscribe tye design), how do you ever know which event structure will handle which event?

By convention, the Event Registration Refnum is wired exclusively to one and only one Event Structure, and this wire is never branched -- the exact same convention as the "Register for Events" node. The difference? The User Event ref remains private to the containing Messenger class; no naked refs are exposed to be manipulated with User Event prims by callers.

Link to comment

...which incidentally demonstrates the beauty and power of separating the messenger (User Event Ref) from the mailbox (Event Registration Refnum).

Just providing an example below to substantiate this vague statement.

NOTE: To demonstrate a growing mailbox, this VI creates a memory leak of 10MB/sec once a "Register Mailbox" button is clicked. It can be stopped by hitting Suspend, Unregister, Kill the Messenger, or STOP buttons. Also note that in a real application, you would handle the events once registered and memory usage would stay appx net-zero; this VI is meant to grow memory unbounded just as a demo.

Try a couple of scenarios, watching the memory usage each time.

  1. Register a mailbox, let it run a moment. Suspend it. Register it again. Suspend it. Unregister it.
  2. Register a mailbox, let it run a moment. Kill the messenger. Note that the memory usage has stayed constant, because the mailbox still exists. Unregister the mailbox. Note memory usage drops to 0.
  3. Try combinations of registering two mailboxes, and note the one-to-many behavior; mailboxes are independent of each other, and independent of the messenger. (There's one behavior I do not understand - when both mailboxes are registered, one would think the memory leak should be 20MB/sec instead of 10MB/sec, but it remains at 10MB/sec. Any takers on explaining this? Is an optimization being applied for unhandled event queues?)
  4. Note that when the VI is first run, messages are being sent, but disappearing into the ether! This is a powerful behavior to have the messenger unaware of whether or not it will create a memory leak if its messages are unhandled (queues don't have the ability to "fire blanks").

For these reasons (decoupling messenger from mailbox, the ablity to fire blanks, and one-to-many), I prefer User Events for interprocess messaging.

post-17237-0-40374100-1348594398_thumb.p

Link to comment

Try combinations of registering two mailboxes, and note the one-to-many behavior; mailboxes are independent of each other, and independent of the messenger. (There's one behavior I do not understand - when both mailboxes are registered, one would think the memory leak should be 20MB/sec instead of 10MB/sec, but it remains at 10MB/sec. Any takers on explaining this? Is an optimization being applied for unhandled event queues?)

I don't have 2012 installed and don't have time to recreate your VI in 2011 so I haven't actually run your snippet, but my guess is that this is a copy-on-write situation. That is, there's only one copy of the event data, and both mailboxes get pointers to that data. A copy is made only when the mailbox reader needs to modify the data. So long as the reader reads the data but does not to write it, there's no need for a separate copy.

Link to comment

Just providing an example below to substantiate this vague statement.

<snip>

For these reasons (decoupling messenger from mailbox, the ablity to fire blanks, and one-to-many), I prefer User Events for interprocess messaging.

On the surface, it looks to me like an anti-pattern (maybe in the minority.....again....lol). The beauty of events is that you can fire them and they don't use resources unless there is something listening for them. That is one of their main advantages over queues This just seems to be trying to circumvent that feature to find a use (a singular use from what I can gather) and it doesn't really add anything to mitigate the drawbacks of events or, indeed, offer anything that cannot be achieved in other ways with more transparent foot-shooting opportunities.

Can you give a real-world example where you might use it?

Edited by ShaunR
Link to comment

Can you give a real-world example where you might use it?

Sure! Consider a simple DAQ loop, generating data. Consider one of many types of listeners (consumers)... a logger, a UI, a server that re-broadcasts the event over a network. The DAQ loop can run headlessly and independently of those subscribed to its messages, and they can come into and out of existence as they please.

Link to comment

Sure! Consider a simple DAQ loop, generating data. Consider one of many types of listeners (consumers)... a logger, a UI, a server that re-broadcasts the event over a network. The DAQ loop can run headlessly and independently of those subscribed to its messages, and they can come into and out of existence as they please.

So how is that any different from anything else (e.g.QE Messaging) except you can create memory leaks?

Link to comment

So how is that any different from anything else (e.g.QE Messaging) except you can create memory leaks?

Thanks for pointing out this thread, it's got some good topics (with limited bandwidth, I had shied away from that thread on principle, since "QSM in a subject on LAVA" usually equals "religious debate" :shifty: )

And the answer to the question "how is that different from anything else" is...

The topology I've now adopted for inter-process comms is a queue for the control, and events for response.

... just wait until the next evolution where you use User Events for both control and response! :D

My proclivity to User Events is perhaps explained by a background focusing on UI and UX design. The ability to combine interprocess commands with UI commands into a single event handler structure is syntactical nirvana. And again, the fact that the User Event Ref and the Event Registration Refnum are two discrete entities - rather than a Queue, where the sender and receiver share the same reference - decouples processes and simplifies philosophical (and practical) issues like ownership and lifetime.

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.