LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Event Structure prevents button from working

Solved!
Go to solution

I'm trying to understand the nuances behind Event Structures.  I have a very simple VI which just has a "Quit" button.  It works great - when the Quit button is pressed, the VI stops:

 

quit1.png

If I add an Event Structure without adding any events, the Quit button no longer works correctly:

 

quit2.png

There is no timeout event and no other events to handle, so why would the presence of the Event Structure interfere with the Quit button?

 

Then, if I add a timeout then the Quit button works fine again:

 

quit3.png

What in the world is going on here?  I do know that adding an event handler for the Quit button fixes the problem, but I'm more interested in understanding better what's happening behind the scenes.

 

0 Kudos
Message 1 of 8
(1,264 Views)

@arcadebench wrote:

 

quit2.png

There is no timeout event and no other events to handle, so why would the presence of the Event Structure interfere with the Quit button?

 

 


That's not correct. There IS a timeout event as evidenced by "Timeout" at the top of the structure. By not wiring it you have left it (the timer) at the default value, which is -1 (no timeout). That means it will wait for an event to fire forever, which never happens since the only event it's listening to is the timeout event that never occurs.

 

You can't delete that event case until you create another one because an event structure with no event cases doesn't really make any sense. (No cases = just delete the structure!) Though I should add that you should only create a structure with no timeout if you know what you are doing and are certain an event will eventually happen. If you are in a situation where you might want the loop to terminate without an event firing then you should wire a value to the timeout so it will eventually stop waiting for an event.

 

For the simplest possible event based architecture, move the button inside the event structure, then right click on the event title and select "Edit Events Handled by This Case...", and change the event being handled to the Value Change event on your button.

 

e.g.:

JimB_0-1660943725131.png

Edit:

 

Just reread your last statement where you say you already know you can add this handler... What's happening behind the scenes is that the Event Structure is basically a function that waits for an event to fire, then executes whatever is inside of the case for that event. You would see the same behavior with "Dequeue Element" or "Wait on Notifier" if you don't wire the timeout. Your button hasn't stopped working without the timeout event, but the while loop will not exit (or move to the next iteration) until all of the code inside of it is finished executing. Without a timeout value, the event structure (or any of those other "wait for something" type functions) will never complete its execution.

Message 2 of 8
(1,251 Views)
Solution
Accepted by topic author arcadebench

@arcadebench wrote:

What in the world is going on here?  I do know that adding an event handler for the Quit button fixes the problem, but I'm more interested in understanding better what's happening behind the scenes.

 


The loop cannot go to the next iteration until everything in it has completed. If no event fires, the loop can never go to the next iteration.

 

Everything that does not depend on other things will execute in parallel.

 

When the VI starts, the button value gets read immediately (still false). When you press the button now, the new value (TRUE) would get read at the next iteration, but it cannot go to the next iteration because the event structure has not finished.

 

You need to fully understand the magic and power of dataflow and thins will be obvious. 😄

Message 3 of 8
(1,221 Views)

Thanks for the clarification.  Coming from C# it's difficult because "events" behave much differently than with LV.  I was hoping for more of an interrupt-driven action - "don't bother (or block!) anything until you're asked to".

 

Having two separate while loops seems to work ok and is a little closer to the action I was trying to achieve:

 

quit4.png

0 Kudos
Message 4 of 8
(1,176 Views)

Another beginner mistake are greedy loop such as your top loop. I am sure you don't need to spin it billions of times per second draining your battery and heating your room. All it needs is e.g. a 50ms wait.

 

See here.

 

LabTOON06132008.png

 

 

Still, all you really need is one loop, one event structure, and events for all user interactions.

0 Kudos
Message 5 of 8
(1,169 Views)

@arcadebench wrote:

Thanks for the clarification.  Coming from C# it's difficult because "events" behave much differently than with LV.  I was hoping for more of an interrupt-driven action - "don't bother (or block!) anything until you're asked to".

It is better to think of LabVIEW events as being conceptually similar to the windows message pump. A queue of events waiting to be processed, and a 'thread' (i.e. While loop) somewhere dequeuing those events and processing them one at a time.

Message 6 of 8
(1,121 Views)

You would need to look at a more complex example to understand how it would work, but splitting your code into multiple loops/VIs where each one is responsible for handling something specific is certainly common. The loops can then interact using various messaging mechanisms (including events). That way, each process can do work in the timeout case of the event structure or delegate it and handle events waiting in the queue when it's done handling the current thing it's working on. DQMH, for instance, is one example of parallel processes communicating using events.

 

Incidentally, you can also handle events using callbacks, which might behave how you want. This is actually the only way to handle .NET events in LV (the register for callback node only exists in the .NET and ActiveX palettes), but it can also be used for LV events. I wouldn't recommend it, because it's more convoluted and doesn't really fit the way LV code works.


___________________
Try to take over the world!
Message 7 of 8
(1,093 Views)

Thinking of the underlying mechanism as a message pump certainly does help.

 

I've been working on a log-gathering scheme (I'll post about it shortly) and was stuck trying to get it working.  Splitting the tasks into two separate loops seems to have done the trick.  I'll check out DQMH as well.

 

The LabTOON was brilliant! 😄

0 Kudos
Message 8 of 8
(1,067 Views)