ldindon Posted March 6, 2009 Report Share Posted March 6, 2009 Hi, I noticed that if your are not able to handle DataChanged events of a XControl fast enough, events will be then stacked causing desynchronization between the data and the display. I have attached a project (LabVIEW 8.6) with the XControl and a simple example (Test.vi) that demonstrates the problem: - The load inside the DataChanged event handler of the XControl is simulated by a "wait for 50 ms". - The data of the XControl is changed each 10 ms. I have also attached some screenshots for those that do not want to run the example. Is there a way to avoid that? Quote Link to comment
LAVA 1.0 Content Posted March 6, 2009 Report Share Posted March 6, 2009 This is always the problem of event driven programming, always make sure you handle the events fast enough. Ton Quote Link to comment
Mark Yedinak Posted March 6, 2009 Report Share Posted March 6, 2009 As Ton mentioned this is a risk of event driven applications. However I would have to ask why you would need to display the changes that frequently. I would question the design in this case and look at your architecture. There is no reason to update a UI display that frequently. A person will not be able to see the updates at that rate and therefore there is no benefit for updating the display that quickly. Quote Link to comment
mje Posted March 6, 2009 Report Share Posted March 6, 2009 QUOTE (Ton @ Mar 5 2009, 05:37 AM) This is always the problem of event driven programming, always make sure you handle the events fast enough. I'll nitpick here, in that it's always a problem with LabVIEW's implementation of events. Other frameworks don't necessarily behave this way. Events can be designed such that multiple signals of the same event over-write the previous signals...I can't remember what this is called. A common example is mouse move events in some architectures...if you're busy handling something, they won't continue to pile up on top of one-another...you'll just get a single mouse move event with the most recent coordinate when you finally get around to handling it. Often I've wished that LabVIEW had an option to support this type of archtecture out of the box, or at least provided more control over the event queue such that it could be put together manually. Quote Link to comment
ldindon Posted March 6, 2009 Author Report Share Posted March 6, 2009 QUOTE (Mark Yedinak @ Mar 5 2009, 04:34 PM) As Ton mentioned this is a risk of event driven applications. However I would have to ask why you would need to display the changes that frequently. I would question the design in this case and look at your architecture. There is no reason to update a UI display that frequently. A person will not be able to see the updates at that rate and therefore there is no benefit for updating the display that quickly. Off course I do not need to update the display that frequently. Unfortunately the XControl architecture does not allow (as far as I know) to update the display less frequently. Each time the data changed the XControl facade ability vi is called to handle the event then the event structure timeouts and the vi exits. If in the meanwhile someone has changed the XControl value 10 times, then 10 events will be stacked somewhere by Labview. It will result to 10 different calls to the XControl facade vi to handle the events one by one. When you are handling an event you did not know that 10 others of the same type are waiting so there is no room for optimization by handling only the last one in the queue and skipping the others. A solution would be to invalidate the display each time the data changed and to update it asynchronously outside the XControl facade vi at a reasonnable refresh rate for instance. But I have no idea how to achieve such a solution with the XControl "API". Quote Link to comment
Mark Yedinak Posted March 6, 2009 Report Share Posted March 6, 2009 QUOTE (ldindon @ Mar 5 2009, 10:35 AM) Off course I do not need to update the display that frequently.Unfortunately the XControl architecture does not allow (as far as I know) to update the display less frequently. Each time the data changed the XControl facade ability vi is called to handle the event then the event structure timeouts and the vi exits. If in the meanwhile someone has changed the XControl value 10 times, then 10 events will be stacked somewhere by Labview. It will result to 10 different calls to the XControl facade vi to handle the events one by one. When you are handling an event you did not know that 10 others of the same type are waiting so there is no room for optimization by handling only the last one in the queue and skipping the others. A solution would be to invalidate the display each time the data changed and to update it asynchronously outside the XControl facade vi at a reasonnable refresh rate for instance. But I have no idea how to achieve such a solution with the XControl "API". What you say is true but since the X-control is a user interface item you could simply gate when you actually updates its value. Internally if you need to work with the latest and greatest value you could use a shift register or some other mechanism which does not trigger the event in the first place. There was another discussion regarding the event structure and its queuing of events which does highlight the desire for the us to have the ability to filter events, discard previous events of the same type or offer some type of "debounce" on the events. Quote Link to comment
ldindon Posted March 13, 2009 Author Report Share Posted March 13, 2009 QUOTE (Mark Yedinak @ Mar 5 2009, 05:47 PM) What you say is true but since the X-control is a user interface item you could simply gate when you actually updates its value. I will not be the end user of the XControl so I have to handle the bad usage of it. My XControl must have the same behaviour as a standard LabVIEW Control. For instance the LabVIEW Gauge is able to handle a value changed at high frequency even if it makes no sense to update it so fast. QUOTE (Mark Yedinak @ Mar 5 2009, 05:47 PM) Internally if you need to work with the latest and greatest value you could use a shift register or some other mechanism which does not trigger the event in the first place. When you said "Internally", do you mean inside the XControl? If the answer is "yes" I do not understand what you mean. QUOTE (Mark Yedinak @ Mar 5 2009, 05:47 PM) There was another discussion regarding the event structure and its queuing of events which does highlight the desire for the us to have the ability to filter events, discard previous events of the same type or offer some type of "debounce" on the events. Thanks I will have a look at this thread. Note: I have attached a screenshot of my Gauge XControl used for prototyping. It does not use ActiveX or .NET and it is multi-platforms (tested on Windows XP and Linux). Quote Link to comment
Mark Yedinak Posted March 13, 2009 Report Share Posted March 13, 2009 QUOTE (ldindon @ Mar 12 2009, 04:54 AM) I will not be the end user of the XControl so I have to handle the bad usage of it. My XControl must have the same behaviour as a standard LabVIEW Control.For instance the LabVIEW Gauge is able to handle a value changed at high frequency even if it makes no sense to update it so fast. QUOTE (ldindon @ Mar 12 2009, 04:54 AM) When you said "Internally", do you mean inside the XControl? If the answer is "yes" I do not understand what you mean. I agree that you need to make your code as bullet proof as possible and you don't have control over how your user's will use your X-Control. I also agree that NI could improve the X-Control itself by allowing updates to be filtered or flushed to allow for situations like this. However, when I was referring to using the value internally I was referring to optimizing the architecture of the code to avoid things like rapid updates to a UI display. In general, it is best to avoid doing this since it will impact your overall performance. I usually don't worry too much about this if the task I am working on will not be doing any type of high frequency calculations or processing. However if I am working on something that will require high performance I like to completely separate the UI from the processing and update it at a rate that is acceptable to humans and still provide "realtime" updates yet don't overburden the application by doing unnecessary work, such as updating the value of a control thousands of times per second. Quote Link to comment
PJM_labview Posted March 13, 2009 Report Share Posted March 13, 2009 QUOTE (ldindon @ Mar 12 2009, 02:54 AM) Note: I have attached a screenshot of my Gauge XControl used for prototyping. It does not use ActiveX or .NET and it is multi-platforms (tested on Windows XP and Linux). Very nice gauge (I especially like the anti-alias). This is funny, I wrote something quite similar about a month ago. PJM Quote Link to comment
Aristos Queue Posted March 13, 2009 Report Share Posted March 13, 2009 QUOTE (MJE @ Mar 5 2009, 10:10 AM) I'll nitpick here, in that it's always a problem with LabVIEW's implementation of events. Other frameworks don't necessarily behave this way. Events can be designed such that multiple signals of the same event over-write the previous signals...I can't remember what this is called. LV's implementation gives you the option of ignoring the events or not, as opposed to us ignoring them on your behalf -- sometimes that's a bad thing. Two options that I know of: You can write your code so that there is a millisecond count in a shift register. Every time you get an event, compare the current millisecond count against the count in the shift register. If the event is too soon, skip the event. Catch the event and rethrow as a different event that is handled somewhere else. As of LV 8.6, there are lossy queue primitives, so you can enqueue your event into a separate handler with the lossy behavior, so if the queue fills up, you just start dropping updates. Quote Link to comment
Mark Yedinak Posted March 13, 2009 Report Share Posted March 13, 2009 QUOTE (Aristos Queue @ Mar 12 2009, 03:02 PM) LV's implementation gives you the option of ignoring the events or not, as opposed to us ignoring them on your behalf -- sometimes that's a bad thing. Two options that I know of: You can write your code so that there is a millisecond count in a shift register. Every time you get an event, compare the current millisecond count against the count in the shift register. If the event is too soon, skip the event. Well, you still end up processing the event to some degree. In the case of this X-Control I don't know if you would really be saving much time. QUOTE (Aristos Queue @ Mar 12 2009, 03:02 PM) 2. Catch the event and rethrow as a different event that is handled somewhere else. As of LV 8.6, there are lossy queue primitives, so you can enqueue your event into a separate handler with the lossy behavior, so if the queue fills up, you just start dropping updates. Unless you end up spawning a background task for your X-Control I don't think this solution would work very well for X-Controls. If you did queue something into a lossy queue what part of your code is servicing it? X-controls are intended to encapsulate the processing required for complex custom controls. I don't think it would be a good idea any of the processing to be handled outside of the X-Control itself (if you did it sort of defeats the purpose of making it an X-COntrol in the first place) and would a separate spawned task from the X-Control itself have access to the display? I guess I would have to look at the rolling LED X-Control example. I do agree with you though that we as programmers need to have control over how the events are filtered as well as if and when. But it would be nice if we had more flexiblity then what we currently have. 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.