Aitor Solar Posted March 21, 2007 Report Share Posted March 21, 2007 When you call a custom property or method in a XControl, the apropiate VI is executed and, after that, the Facade VI is called to update the changes. OK. But it seems LV returns the control to the external VI before the Facade has finished. So if you write a property and inmediately read something that depends on it, you'll get the previous value, not the one you have just written. This can lead to problems. For example, I have implemented a property that tells the Facade to make invisible some elements, then I call the XControl "Get Image" native method. The resulting image has the elements that should have been inivisible, unless I put a delay of about 15 ms between the property and the method :thumbdown: . Saludos, Aitor EDIT: I have attached an example; open try.vi in the llb. This VI generates a random number and passes it to the custom "New value" property. This property updates the XControl value, but before that, the VI continues executing and gets the old value. If you make the delay to 10-15, the behavior is corrected as the Facade has enough time to finish before the external value is read. Quote Link to comment
Michael Aivaliotis Posted March 22, 2007 Report Share Posted March 22, 2007 First of all. This example can be fixed. If you put a delay of 1ms, then it works. Another way is to NOT create a custom property to do something that the built-in Value property already can accomplish. If you use the native value property (to write the data) it works fine. I understand the point of the example is to emphasize the problem but I'm just stating this here for the record. This is a known issue with XControls and I'm not sure if NI is working on a fix or not (probably not). This is simply an issue of a race condition inherent to how the XControl works. Reading from a terminal does not require a call to the XControl Facade (only the data store) which means that it is asynchronous to the facade operation. You can write to a property, and read from the terminal (or native value property) before the Facade has a chance to update the internal data store with the new value. Your other example about the "Get Image" native method is similar since it does not wait for the Facade to complete the work it has to do. I suggest a workaround is to implement your own replacement "Get Image" which does the same thing as the native one. The difference is that it will force the Facade to execute thus avoiding this problem. XControls are a Bitch! Good luck! Quote Link to comment
Aitor Solar Posted March 22, 2007 Author Report Share Posted March 22, 2007 QUOTE(Michael_Aivaliotis @ Mar 21 2007, 10:45 AM) First of all. This example can be fixed. If you put a delay of 1ms, then it works. Hey, good machine . In my PC I need 10ms, and its a 2.8MHz Dual Core. QUOTE(Michael_Aivaliotis @ Mar 21 2007, 10:45 AM) Your other example about the "Get Image" native method is similar since it does not wait for the Facade to complete the work it has to do. I suggest a workaround is to implement your own replacement "Get Image" which does the same thing as the native one. The difference is that it will force the Facade to execute thus avoiding this problem. In fact, all of this started when I tried to implement my own GetImage method, something I've been uncapable to do in a simple way (the GetImage example I mentioned is just the solution NI suggested). So maybe I'm doing something wrong. Let's call the new method GetImage2 to avoid confusion with the native one. I want GetImage2 to recieve a background color, make a native GetImage method on one of the Facade controls and return the resulting image. The way XControls' methods are implemented, you can only handle the State cluster values and after that, Facade will be called. So: 1) I can't have the image data as a State element, since that image depends on the background color (and I don't know the BGcolor until the method is executed). Moreover, having always an image in the cluster and updating it whenever is a change in the Facade seems overkilling and will make the XControl heavier in memory terms. 2) I could have, in the State cluster, a reference to the control whose image I need. That refnum can't be initialized in the Init VI, since the control is in the Facade VI. So, I can make a custom property to initialize that refnum ("InitRefnum") and call it always before GetImage2. But that's error prone (the end programmer can forget it, or we could fall again into a race condition). It would be great if GetImage2 could call internally InitRefnum to avoid problems, but is impossible to call an XControl custom property or method inside another custom property or method (it leads to recursion). 3) So, I could initialize that refnum in the Facade's Timeout event case just to be sure. But I'd prefer to do nothing in the timeout (I think this very issue was commented here about Ton's XControl creator). And that would add unnecessary code executed every time the Facade is called. 4) Minor issue: after doing all that, Facade is executed to do nothing. Why I can't decide if I need it or not? 5) If there has been an error in all the process, I'd like the invoke node error output to carry it. But that seems impossible (the "error out" cluster in the Method template doesn't go to the invoke node error, it seems get lost). I'd have to create an additional output in GetImage2 and check it in the external VI every time I call my method, just to see if has worked fine. I hope to be mistaken in any point, but the way I see it, it harldy worth the effort . Saludos, Aitor 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.