02-16-2023 06:03 AM
I've just been reviewing some code, and it made me ask myself a question I couldnt find the answer to... Is there a defined, definite order in which a LabVIEW event structure will handle two value change events for the same control - one registered as a standard user event and one registered as a dynamic user event using the control reference?
In the snippet below I setup a test for this, and as far as I can see, the user event (direct value change event) always happens before the dynamic version of the event... but is that chance or is that expected behaviour?!
I realise it may be questionable to do this, and that's another separate issue, this came up as we have a template UI which typically handles all UI value change events in one case using the dynamic user event registered for all front panel controls, but one of my developers has needed to add in some specific handling for one control, so the value change essentially triggers both cases. But then order of events may be important in the final behaviour of the code...
Anyone able to shed any light on whether this is opening a risk of race condition (i.e. between which case runs first) or if the event handling code is set up in such a way that user events are always handled before dynamic events?
Cheers!
Paul
02-16-2023 06:39 AM
Educated guess, if something triggers several events at once, they'll occur in the event list order. Move your User event before the registered standard event and see if the execution order changes.
02-16-2023 06:40 AM
There was an NI Week presentation that went through all of the caveats of Events immediately after a major refactoring of the event backend. I think it was in 2014. It might be able to shed some light on your issue.
The following is my speculation, so it may not be correct:
I would say you are open to a race condition. The Event Structure just has a FIFO for the event queue. So whatever gets in first will execute first. However, the static event has less code in order to get the event into the queue. The dynamic event has more lookup in order to see if it should be put in the queue. So 99.999% of the time, the static event will beat out the dynamic event.
02-16-2023 07:02 AM - edited 02-16-2023 07:03 AM
This kind of goes into the minutiae of how events are handled.
The following may be incorrect, I'm not part of LabVIEW R&D, but this is my observation:
The point in time where the two events are actually being registered are different. You register for the "dynamic" event after the VI has started running, but the "static" event is registered as soon as the execution state of the VI changes to "running". This is an inherent difference which cannot be overcome without registering the "dynamic" event outside the VI and feeding in the event registration refnum as a parameter.
So once you have events registered, typically an internal 64-bit timestamp is used to distinguish which events were fired first, and they will be handled accordingly. In this case, the timestamp is identical since they're actually all registering for the same event. In this situation, I could imagine that once the timestamps are identical, LabVIEW simply follows the order of registration. This is at least internally consistent to how filter events work, the order of execution of filter events depends on the order of event registration.
So that would be my guess. Since your "static" event is registered first, it is handled first when the timestamp of the actual event is the same.
Edit: I generally try to NOT mix dynamic and static events int he same event handler. Can't say precisely why, I've just grown to adopt that methodology. There's probably a reason, long forgotten.
02-16-2023 07:58 AM - edited 02-16-2023 08:06 AM
So, so far...
I guess the long and short is, it probably needs to be refactored away from handling the same event in more than once event case (which is essentially what's happening here), so I shall go with that. Would have been nice to know if there's a definite answer somewhere though!
Thanks all for your input!
02-16-2023 09:50 AM
It's logical is all fixed/static events are registered first, before all dynamic events. If triggered it looks through some "registered event" list so that the statics fire first. But since it's not specifically written in the help, it can be dangerous to rely on such behaviour. If somehow using multiple events for one action they shouldn't have any dependencies. I'm trying to come up with a situation when it would be beneficial, but i'm sure there are good use cases for it.
(The only thing that comes to mind is e.g. to have a Value change event on some array/cluster and a registered one for a specific element in the cluster, e.g. a color box, then the array event could do some calculation or something, and the color box one could update some graph or picture)
02-16-2023 10:34 AM - edited 02-16-2023 10:36 AM
My personal approach would be to put all the UI events in a separate loop and have them simply call the core dynamic event.
This solves a lot of headaches in this regard.
By maintaining a single entrypoint (the dynamic event) all kinds of nastiness goes away.
02-16-2023 11:10 AM
@crossrulz wrote:
The following is my speculation, so it may not be correct:
I would say you are open to a race condition. The Event Structure just has a FIFO for the event queue. So whatever gets in first will execute first. However, the static event has less code in order to get the event into the queue. The dynamic event has more lookup in order to see if it should be put in the queue. So 99.999% of the time, the static event will beat out the dynamic event.
I strongly doubt there are parallel bits of event-generating code that can race. The "filter" and "lock front panel" event handling basically requires there only be one thread running this code (else one could have a static "Mouse Down" fire before a dynamic "Mouse Down?"). This will be running strictly in the UI thread.