01-13-2012 01:19 AM
I am using splash screen to start an application. I use dynamic loading of the Main.vi and an animation during the loading, both in parallel threads (see image below). However, when the Open VI reference VI is called everything else stops executing (the animation stops running) until the Open VI reference is done. I must call the Main.vi dynamically, because it takes some time to load and I want to notify a user that the application is loading (using animation). Is there an option to prevent the Open VI reference to block the execution of other threads? Or should I use some other approach?
01-13-2012 02:17 AM
You could try start asynchronous call
http://zone.ni.com/reference/en-XX/help/371361H-01/glang/start_asynchronous_call/
01-13-2012 07:39 AM
THe stall durring loading is porbably Winodws when you chase it to the end since loading requires reading the file and mapping it to virtual memory which for the most part is Kernal work where time-sharing is a no-no until the mapping is complete and its safe to exit the Kernal. (YOu can confirm this using the Windows Task manager if you show "Kernal Times").
SO to get it to load faster you can ask windows to do the work in smaller chunks. This can be done by loading te Main VI from the bottom up meaning open the VIs at the bottom of the hiarchy first so they are already in memory when their callers are loaded. At the end load the main and run it.
Note:
Loading from the bottom up assumes there are sub-VIs.
Ben
01-13-2012 07:55 AM
OR, try writing / reading slider and end directly from the terminals- this will avoid the top loop waiting for the UI thread that the bottom loop is running in
01-13-2012 09:01 AM
Jeff, I don't understand what you mean? Could you explain it a little bit more.
01-13-2012 10:11 AM - edited 01-13-2012 10:13 AM
The Run.VI method requires the user interface thread "THE UI Thread" there is only 1 so any other processes the need the UI Thread are blocked as this method completes. Writing and reading from property nodes also require the UI Thread this is what you see when the animation "stops."
Ben's sugestion of preloading the sub.vis is actually A great idea and the lower loop would look something like this. with a little additional data dependany to ensure the loop finishes befor the invoke node - sorry I was rushing
This allows the upper and lower loops to share updating the UI Thread by pausing between the loading of each vi so the top loop can apply the changes that are pending. Write to terminal places the new data in a pending buffer but you still need a thread switch to actually update the FP while P-nodes won't return untill the update happened under most conditions (unless the defer FP updates method is run first- but thats another subject)
01-16-2012 01:49 AM
But the problem is not in the Run.VI method because the Open VI Reference blocks the execution of the top loop and I need the Open VI Reference to call the Get VI Dependencies method. Other approach could be to create a static array of dependencies and then to use this array to load VIs from bottom up.
The only question now is if the Get VI Dependencies method returns dependencies in top to bottom order? If it does then I can just load VIs in reverse order from the array.
01-16-2012 05:56 AM - edited 01-16-2012 05:58 AM
@andrej wrote:
But the problem is not in the Run.VI method because the Open VI Reference blocks the execution of the top loop and I need the Open VI Reference to call the Get VI Dependencies method. Other approach could be to create a static array of dependencies and then to use this array to load VIs from bottom up.
The only question now is if the Get VI Dependencies method returns dependencies in top to bottom order? If it does then I can just load VIs in reverse order from the array.
Well the problem is the Open VI Reference! This executes in the UI thread, as several people have explained already (and really can't be made to do otherwise without causing a number of possible and nasty race conditions, some of them even related to the underlaying OS and not just LabVIEW itself), just as your two Property Nodes in the upper loop have to use the UI thread too.
Once Open VI starts it only returns if it has loaded the required VI fully into memory (and that includes any dependencies that aren't already in memory) and linked them all properly together or runs into an error during loading. For this duration, NO UI Property Node can execute, which is what stalls your upper loop. If you would use local variables or terminals instead the upper loop would happily run along while Run VI loads the entire VI hierarchy but it would still not show on the UI, because in order to draw the new data from the diagram passed to locals and terminals LabVIEW has to catch the UI thread to do the UI drawing.
So first fix is to kick out any property nodes from the upper loop and the second part of the solution is to load your VI hierarchy in chunks instead of simply loading only the top level VI directly. It would be nice if Open VI had an option to allow UI thread release between loading of chunks of VIs, but the implications are not that nice. It would be quite easy for an uncareful LabVIEW programmer to create a lockout situtation then, where two functions are in fact waiting on each other to release some locks so that the program gets hang up. And a simple warning in the documentation to watchout as this option can allow to create such lockout situations is not very useful as nobody reads them anyhow.