LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to stop an application?

Hi,

 

this subject has been discussed many times, but I have not found really relevant info for anything more complex than a project vi only couple VIs.

 

Our project has about 20 modules running in parallel. Theoretically speaking each one of them should be able to stop all the rest in a controlled manner, but in reality the ability to stop the app is restricted to couple modules. Each module has several subVIs inside as expected. So of these subVI should constantly do things others really has to take action based on events.

 

The first iteration of our "AppStop" VI (AS) was a latching FGV. I had a "Stop App?" input and a "Stop App!" output. If anybody sets the input to true from that point the true value is latched and everybody else everywhere will know that its time to stop. Now the problem with this, is that we have VIs really should sit idle in 99.9% of the time but to realize that it should stop it needs to poll the AS vi periodically. This - in my opinion - messes up the VI as however its functionality doesnt require constantly doing something, I have to apply some sort of a continous reading of the FGV. It also makes debugging harder cause now the VI is contionusly doing something while just by its function it could stay rest.

 

To mitigate the problem I thought that I will make the AS event based, so whenever the Stop App? set to true it generates an event. The subVIs register to this event and act accordingly. This works very well in simple VIs which practically has only an event structure, but for more complex VIs its possible that we lose the event as it might be generated when the execution is in between two event structure (one of them is not processing it anymore the other one is not registered to it yet).

 

So I have ended up using both the method, some VIs stop based on the latched output, some stop based on the event. But it stinks to me, and I believe there should be a cleaner way to solve this.

 

Let me know your thoughts.

0 Kudos
Message 1 of 18
(2,044 Views)

To Stop multiple VIs or Loops , I Prepare to use Notifier with Enum/Boolean, Where I will be reading the notifier status continuously in the Loop and whenever it notifies as exit I will be exiting the Loop or the Module.

 

I have 10+ Loops Running in parallel and I could Stop instantly.

----------------------------------------------------------------------------------------------------------------
Palanivel Thiruvenkadam | பழனிவேல் திருவெங்கடம்
LabVIEW™ Champion |Certified LabVIEW™ Architect |Certified TestStand Developer

Kidlin's Law -If you can write the problem down clearly then the matter is half solved.
-----------------------------------------------------------------------------------------------------------------
0 Kudos
Message 2 of 18
(2,020 Views)

As far as I understand this is pretty much the same contionusly reading a latching FGV, exactly what I try to avoid.

0 Kudos
Message 3 of 18
(1,990 Views)

@1984 wrote:

As far as I understand this is pretty much the same contionusly reading a latching FGV, exactly what I try to avoid.


well there's this

 

 
alexderjuengere_1-1705668422588.png

 

 

 

 

https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000YI57CAG&l=en-US

 

 

I assume, "Abort VI" in the above picture is like pushing the red stop button , or using https://www.ni.com/docs/en-US/bundle/labview-api-ref/page/functions/stop.html

 

0 Kudos
Message 4 of 18
(1,966 Views)

Using the stop function or aborting the VI is the exact opposite of stopping a VI in a controlled manner, so these two can not be used and generally should be avoided.

0 Kudos
Message 5 of 18
(1,938 Views)

Don't unregister/reregister the event between event structures.  Use the same registration for both event structures.

Register the event when the VI starts; unregister it when the VI exits.

0 Kudos
Message 6 of 18
(1,923 Views)

I am a fan of the Channeled Message Handler. In my case I have several loops running in parallel.

Each loop is basically a State Machine so every loop has an "Exit" state.

The main control loop sends an "Exit command" to all the other loops, waits for an ACK that each loop has stopped and then stops itself and the program exits completely.

========================
=== Engineer Ambiguously ===
========================
Message 7 of 18
(1,916 Views)

@paul_a_cardinale wrote:

Don't unregister/reregister the event between event structures.  Use the same registration for both event structures.

Register the event when the VI starts; unregister it when the VI exits.


If I understood this right then I dont think it helps. Lets say one of my modules have a loop which has three VIs connected in series. All of them are doing their job until they finished with it OR if an AppStop occured somewhere else. That "somewhere else" VI generates an AppStop event and lets say that event is captured by the first VI in the series so it stops. But as the event is processed in one of the event structures it wont trigger an even in the second VI.

 

It is possible and I considered that if an event structure captures an AppStop event than it immediately triggers another event. By this I can guarantee that every event registered to the AppStop event will stop, but at the same time it forces the programmer to not forget putting a new event generation in every AppStop case which is a pretty inconvenient and error prone coding standard.

 

Another option is creating a module which starts at the very beginning of the application and registers to the AppStop. Once it got the event it starts flooding out AppStop events lets say in every 10ms all the way until at the very end of the main application (when we know that everybody has stopped) we can stop this module. This could work and doesnt give the programmer too much extra work but it doesn't look very elegant. 

Message 8 of 18
(1,825 Views)

@1984 wrote:

If I understood this right then I dont think it helps. Lets say one of my modules have a loop which has three VIs connected in series. All of them are doing their job until they finished with it OR if an AppStop occured somewhere else. That "somewhere else" VI generates an AppStop event and lets say that event is captured by the first VI in the series so it stops. But as the event is processed in one of the event structures it wont trigger an even in the second VI.

 

It is possible and I considered that if an event structure captures an AppStop event than it immediately triggers another event. By this I can guarantee that every event registered to the AppStop event will stop, but at the same time it forces the programmer to not forget putting a new event generation in every AppStop case which is a pretty inconvenient and error prone coding standard.

 

Another option is creating a module which starts at the very beginning of the application and registers to the AppStop. Once it got the event it starts flooding out AppStop events lets say in every 10ms all the way until at the very end of the main application (when we know that everybody has stopped) we can stop this module. This could work and doesnt give the programmer too much extra work but it doesn't look very elegant. 


You certainly shouldn't need to send multiple AppStop, then you have some bad design. If VIs are serial it's easy enough to send out a Stopped boolean or simply set an error "User stopped" that'll prevent the following VIs to run.

As for parallell tasks, a Notifier or Event solves it well.

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 9 of 18
(1,815 Views)

 

You certainly shouldn't need to send multiple AppStop, then you have some bad design. If VIs are serial it's easy enough to send out a Stopped boolean or simply set an error "User stopped" that'll prevent the following VIs to run.

As for parallell tasks, a Notifier or Event solves it well.


As I wrote above my VIs use event structures. If during the execution of VI#1 the event occurs it stops VI#1, but then VI#2 again registers the event (or I roll the dynamic event terminal from VI to VI) as the event is alreay fired it just stay there.

 

I could query the notifier status periodically but right in the original post I mentioned that I'd like to avoid continously polling something in the timeout of the event structure. As this would be a very simple latching notifier I wouldn't even bother using it cause I could use a latching FGV.

 

Stop boolean? Sure it might work if you have four VIs, not when you have hundreds. Plus of course does not work with events.

 

An error could be used, thats true. Its not the holy grail thoughas at a certain point I need to differentiate between "non-critical" and "app stop" type errors which again introduces a new coding "must do".

 

 

0 Kudos
Message 10 of 18
(1,803 Views)