LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
Mads

Calendar control that does not block the GUI

Status: New

If you click on the calendar button of a date & time control all updates of the user interface and all functions that happen to run in the user interface thread are halted/blocked.

This is, as far as I know, because the calendar is really an ActiveX control...We need a native control that does not show such behaviour (especially considering the fact that things like the run method is running in the user interface thread...).

 

It is quite ugly that such a fundamental control as the date & time control depends on code that will block the GUI. 

32 Comments
AristosQueue
Proven Zealot

> That's pretty dismissive.

 

I didn't intend for it to be dismissive of the idea of changing it. I read your message as needing a campaign to make NI aware of the issue, and I was trying to say that the behavior is known and you don't need to make _NI_ aware of the issue. Spreading the word among relevant customers is a different issue.

Mads
Active Participant

That's OK.

 

In the start of the thread it did not seem like a known issue (the first reponse was not: "hey, haven't you heard about the root loop, read about it here and here...", that was probably because the first description was not very precise though), but yes - my primary goal is to get a solution AND the secondary is to make other *users* aware of the issue and/or tell NI that they feel this problem as well. Incidently the latter often makes it easier to get the former.Smiley Wink

 

Silmaril at LAVA commented on a related discussion with this:

 

"I think there are two options how NI could improve this in future versions of LV:

  • The Run VI method could be improved so that it may be executed even while the UI thread is busy (or there might be a new method to do this).
  • The code that handles the menu could be improved so that it does not block the UI thread all the time (it's not doing much anyway, so why does it have to block this thread?)."

My hope when you first mentioned that it would probably not be solved anytime soon was that it would still be possible to do what Silmaril mentions at the end of the first option: namely to create another method just for this purpose. If such a creation would be possible if only some limitations were put on it (which you cannot have with the existing run method) then such a solution would be welcome as well (my guess is not, but anyway...).

bob@prolucid
Member

Back to the initial problem posted.

 

Aristos, can you confirm that this behaviour does not affect dynamic launching of class VIs?  I believe that classes do not run the UI thread but I want to be sure.

 

Also some feedback, I've been using LabVIEW fro 10 years and have taught the LabVIEW courses for most of that time and I am embarrased to say that I didn't realize this could be a problem.  (However, most of the plug-ins that I have written are pre-loaded on initizlization of the code and that seems to avoid any thread lock issues.)  There is a whole section of the LabVIEW Core courses that promote a plug-in/dyanmic architectrue.  I don't think this UI lock issues is covered in the course but I will definately be adding it the next time I teach that section.

 

 

AristosQueue
Proven Zealot

> Aristos, can you confirm that this behaviour does not affect dynamic

> launching of class VIs?  I believe that classes do not run the UI thread but I want to be sure.

 

By the phrase "dynamic launching", I'm not sure if you mean "dynamic loading into memory" or "dynamic dispatch calling." I'll answer both...

 

UI Thread and Root Loop are two different issues. Root Loop is an even tighter requirement than UI Thread. Classes do not run in the UI thread, but they do require Root Loop in order to load into memory (because VIs require Root Loop in order to load into memory and classes load VIs). So, dynamically loading a class is subject to the Root Loop restriction, but just dynamically calling a member VI is not bound to the UI Thread at all.

 

> are pre-loaded on initizlization of the code and that seems to avoid any thread lock issues.

 

Also, any plugins that load in response to user interface actions are also free of these issues. It is only plugins that are being programmatically loaded on behalf of the program as opposed to on behalf of the user. In other words, a very rare use case compared to the vast majority of plugin systems.

 

> There is a whole section of the LabVIEW Core courses that promote a plug-in/dyanmic

> architectrue.  I don't think this UI lock issues is covered in the course but I will

> definately be adding it the next time I teach that section.

 

Just be sure to give it the proper downplay. I do not want people thinking that this affects most plugin systems. It doesn't. And even if it affects them, that is honestly unlikely to be a significant problem since it only hangs while the user does something typically short lived.

AristosQueue
Proven Zealot

Reading prolucid's comments made me a bit paranoid that others reading this thread might miss the subtlety of this issue. So here's as clean an explanation as I can provide:

 

Most nodes in LabVIEW can be performed in any execution thread.

Some nodes in LabVIEW can be performed only in the UI thread. The UI thread may cooperatively multitask many of these simultaneously.

Fewer nodes in LabVIEW can be performed only in the UI thread if there are no other cooperative multitask activities going on. We call these actions "requiring root loop".

 

In LV 2011 and earlier, one operation that requires root loop is Open VI Reference. (I add the version caveat only because things do change and I want to be clear what versions this all applies to. Please do not read that as implying that anything will change. Likewise, please do not read this disclaimer as implying that nothing will change.)

 

If your plug-in system works by "User clicks on a button or chooses from a menu or takes some action and in response I load this plug-in VI", you are not affected.

If your plug-in system executes while the user interface is locked (busy wait cursor, panel not open, etc), you are not affected.

 

The above use cases are by far the most common use cases for plug-ins, and they work fine.

 

This issue ONLY affects plug-ins that are dynamically loaded into the backgorund while the user is free to click on other things. Suppose you have a loop that is handling a user interface. Independent of that, you have a loop that reads data from some source and, based on the value of that data, loads different VIs into memory. In this case, operations that require the UI thread participate in cooperative multitasking will lock out the loading of the plugin until the UI thread is no longer busy. These include tracking a popup menu, a drop menu, or showing the calendar of the timestamp control.

 

Being affected is not necessarily a problem for your application. The loading of the plug-in will proceed just as soon as the load can get time on the UI thread by itself -- so when the user closes the menu or closes the calendar. Most apps are fine with this -- the user rarely does anything that ties up the UI thread for a long time, and because "load from disk" is not a deterministic operation, the rest of the code cannot be dependent upon the plug-in loading within a defined amount of time. These two facts mean that most people will never be aware of this issue.

 

Cooperative multitasking lets most VIs do UI work regardless of what other VIs are doing. Interestingly, once an operation requiring root loop gets going, other tasks that only need cooperative multitasking can often proceed, just not another event requiring root loop. There is (at least) one operation that actually locks out cooperative multitasking: Call Library Nodes that are configured to run in the UI thread. Once one of those starts, nothing in the UI runs until the thread returns.

 

I hope that summary helps clarify the issue.

rolfk
Knight of NI

Mads wrote:

 

>I've developed in LabVIEW myself continously since 1997, and have not noticed it for all this time, but then again most of the programs of ours that do dynamic instatiation of background processes and >have a GUI are more often than not used via remote clients (served by that same dynamic instatiation...(!)) instead, so the odds of a freeze is so low that it can take a long time before the >first occurrence. It is an intolerable risk though, and we will have to migrate away from it somehow.

 

This fact alone seems to be a pretty strong indication that this problem is not at all such a show stopper as youo seem to want to make it. Also it is not a freeze of the application but a postboning of some pretty rare and unlikely operation while a user decides to open one of those dialogs without acknowledging it.

 

And the root loop has been discussed extensively on Info LabVIEW several times in all those years. So it is also not an unknown thing but just some that you may have missed for some reasons. There are several places in the documentation of LabVIEW that talk about it too. So yes it exists, it can be an issue under rather exeotic conditions and it is because of that relatively unknown, despite the fact that it has never been hidden by NI in any way but they openly discussed it (Greg Mc Kaskle was one of the LabVIEW developers giving more insight into the root loop in some of the Info-LabVIEW discussions) and even documented it. Things like popup-menu handling are in fact handled in most Windows applications by a tight control loop that captures the Windows event dispatch mechanisme for the entire process. It is how Windows was designed to handle this, and requires a rather involved infrastructure in the application to avoid it.

Rolf Kalbermatter
Averna BV
elset191
Active Participant

I just had my DAQmx Watchdog expire because I opened a calendar browse window.  Reading through this thread it is not entirely clear to me why or what I should do to work around that. 

 

I've started a thread on the LV forum for discussion.

--
Tim Elsey
Certified LabVIEW Architect
AristosQueue
Proven Zealot

elset191: There is not a direct workaround other than "do not use that control." Your closest workaround that I know of would be:

1. Hide the Browse button on the time stamp control.

2. Add a new button to your panel that looks just like the timestamp's browse button.

3. When users click that button, run this VI:

          resource\dialog\picktime.vi

4. When that subVI returns its output, set that as the value of the timestamp control.

 

That will give you a control that avoids the root loop issue.

elset191
Active Participant

Thanks, Aristos.  I had just hid the button.  Didn't realize the picktime.vi was inherently different.  The impression I had reading this thread was that the browse button called that VI, and it was doing the blocking.  I'll give that a go tomorrow

 

 

--
Tim Elsey
Certified LabVIEW Architect
AristosQueue
Proven Zealot

It does call that VI. The problem is with *how* it calls that VI. Calling from G code is fine. Calling from the C++ code is not. Long story there.