Unfortunately I can't send that project for someone to look at, but I made a small project of what I'm trying to get working. Been wrestling with this for a while and the quality of my ideas is not getting better. Need a cup of coffee, or maybe three, or a vacation.
So in the actor core there are two buttons. When user presses the button 1, it should launch Button 1 pressed.vi.
Button 1 pressed.vi waits in while loop for user to press Button 2 or that the program is shut down.
And now even the messages doesn't seem to work in my example, I'll post this anyway if someone has nothing better to do for weekend, you can teach me Labview. So what is the magic to get the stop event working in the Button 1 pressed.vi?
1.) Don't set up dynamic events for buttons, use standard front panel events instead
2.) Pre-launch initialisation of stop event is ok.
2.) DON'T unregister / destroy event/ references in stop core. This must not be done until the event handling loop has stopped.
It looks a little like not seeing the woods before trees. I highly recommend event basics for the weekend schedule.
You actually can immediately destroy the user event after firing it and trust that the register for events function will always catch it 🙂
This means that stop core can generate the user event and immediately destroy it without worry.
The helper loop can call the unregister for events function after its loop has exited.
I really appreciate all your input, thank you.
I modified the project to closer of what the situation is in my "main" project.
There is a calling actor and nested actor.
If I run the launcher and then right away quit the program with X on calling actor, everything shuts down.
If I run the launcher, and press button 1, execution moves to "Button 1 pressed.vi"
then press button 2, that event goes to "Button 1 pressed.vi" and quits it, after that quitting the Calling actor with X shuts everything down nicely.
If I run the launcher, and press button 1, execution moves to "Button 1 pressed.vi",
then press X on calling actor, the stop event does not go to "Button 1 pressed.vi" and it keeps running.
So why does the button event go to the "Button 1 pressed.vi" but the stop event does not?
Is there a way to get the "Button 1 pressed.vi" notice that stop event?
And please respond with 2017 format.
It's hard to say because unfortunately your architecture is flawed from the start.
Your button handler VI is blocking, which is a big no-no for AF messages. Messages are handled in Actor Core. When Button 1 pressed.vi runs, that Actor Core can *never* stop until that VI returns. You're sending the Exit user event in Stop Core, which runs *after* Actor Core.
Since Actor Core can never stop, Stop Core can never stop, which means it never sends the message.
Having a blocking architecture with dynamically registered user events is a poor design that should only be considered if you REALLY know what you're doing. Instead of having the message block, have the message set a flag and return immediately. Handle all of your events in messages. When Button 1 gets pressed, set an internal flag that says Button 1 pressed. When Button 2 gets pressed, have it check for the flag. If it's set, close the VI or do whatever it is you need to do. If it's NOT set, don't do anything (since Button 1 hasn't been pressed yet).
I would caution you against using dynamically registered events in a button handler. Even a *blocking* message is generally a Very Bad Thing (tm). If you have a blocking task (like waiting on IO), put it in a helper loop. Blocking messages are bad because NOTHING else can happen while that message is being handled- no more messages, no Stop Core, literally nothing else with that actor.
Thanks, I'll have to change the architecture.
Would've been nice to run that kind of parallel while loop outside of actor core.
Because the button event could get to the other vi outside of actor core I thought that also the stop event could.
It's not a matter of not being able to "get to" each other (because they can transfer just fine), it's just that you wind up never sending the Stop event at all.
If you had another helper loop in Actor Core that detected Panel Close? and sent the Stop event, it would work, but I'd recommend against that architecture.
Basically the AF does this:
Pre-launch init -> Actor Core/Handle Messages -> Stop Core
Since Stop Core doesn't run until all messages have returned, and your message doesn't return until Stop Core runs, you wind up with a deadlock. It's a matter of when it's *sent*, not how it's received.
When browsing AF discussions I saw that queues are used for handling multiple helper loops.
Anyway I'll need more than one helper loops so is it good architecture to have queues in actor core to communicate between helper loops?
If I have one while loop with event structure to capture the stop event.
In that event case write stop message to queue.
Other loops read the queue and when stop message is received they stop themselves.
Does that stop message get sent to the queue and is it received by other loops? Or does the stop event somehow have effect on queue message getting through?
Saw some example where while loop was stopped with "get queue status" and error from that, that's why I'm asking if the last message still gets to the other loops.