LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Ensure Completion of Asynchronous Loops from User Event

I have a Main.vi that generates user events which are received by 2 Asynchronous (x80 called) SubVi's. However, I need to eliminate a race condition when I'm saving my data.


What is the best way to make sure that my SubVi's have finished their tasks (saving their data to a common folder) before my Main.vi zips the data and archives it to a database?

My gut solution is to have an FGV/Action engine passed between the VI's that will act as a busy flag, but I don't know if there is a better way.

 

0 Kudos
Message 1 of 6
(658 Views)

Do the asynch subVI's finish executing when they're done? If so you can use the "Prepare to call and collect" then have Main wait on them to return data.

 

If they're constantly running, I'd use a queue to send messages back from the subVI's to the Main VI. With Main generating user events, you can add a temporary return queue refnum that Main generates then sends to the subVI as part of the user event data it sends (or as a new user event). When it's done, it sends a message to the return queue that tells Main that it's finished, then Main can release the temporary queue reference.

 

You can use an FGV but I tend to not like that style of communicating between async loops; it's easy to add race conditions and it's a little harder to scale, plus it means Main has to poll the FGV instead of allowing Main to wait on queue data to come in.

0 Kudos
Message 2 of 6
(638 Views)

Since you are using User Events, I will assume that you are sending User Events to your asynchronous subVIs.

 

  1. One method - Send another User Event back to Main.vi when complete.
  2. Second method - Use the Event Inspector to check if those event loops are still active. Attached VI below based on @Hooovahh's work. If they are active wait until done.

mcduff

snip.png

 

 

 

0 Kudos
Message 3 of 6
(628 Views)

Sounds "needlessly complex" to me (but then I don't really know nor understand the requirements of the task).  Are the Asynchronous VIs basically a way of "spawning" parallel processing VIs without having a "bare VI" icon on the Main desktop (I'm ignoring, for now, the notion that you might want Main to do "15 steps, then spawn the sub-VI as a parallel process)?

 

I've been using a QMH-like design for my Main and for my Parallel Loops.  Since a Message Handler basically "waits for a Message", Main can "start" Parallel Loop 1 by send it Loop 1's "Initialize" Message.

 

As a result of this simplified Design choice, the code is pretty easy to explain to my colleages (I just gave a 4.5 hour presentation on it, and some of the "tricks" and "What NI Forgot to Put In" that I used ...).

 

Bob Schor

 

 

0 Kudos
Message 4 of 6
(606 Views)

@Bob Schor

 

Here are some potential use cases, that I actually use.

 

  1. I launch an asynchronous dialog box that the user can respond to. I do not want the dialog to hold up the program unless I need it to, for example, maybe the dialog is only informational and not important. I launch the VI asynchronously and I can have it listen in to Main VI via User Events, and yes, the same thing can be done with queues, maybe even Channel wires. I can also relay information back to the Main VI with the User Event.
  2. I use User Events to communicate between loops. Like queues they are lossless, if there are listeners present, if not, the message is lost. So I use the VI I posted earlier at the start of my program to make sure all the loops are running before I send any messages out to avoid losing information.

mcduff

0 Kudos
Message 5 of 6
(599 Views)

@mcduff wrote:

@BOB Schor

 

Here are some potential use cases, that I actually use.

 

  1. I launch an asynchronous dialog box that the user can respond to. I do not want the dialog to hold up the program unless I need it to, for example, maybe the dialog is only informational and not important. I launch the VI asynchronously and I can have it listen in to Main VI via User Events, and yes, the same thing can be done with queues, maybe even Channel wires. I can also relay information back to the Main VI with the User Event.

mcduff


Ah, yes, Channel Wires (my #1 favorite new feature in LabVIEW).  You cannot (ordinarily) pass a Channel Wire into a Start Asynchronous Call.  I have a routine that has multiple (up to 24) identical Asynchronous Clones, and (almost) everywhere I use Channel Wires, predominantly Messenger Channels to create a Channel version of the Queued Message Handler (I call it the CMH).  The only place I use a Queue is as the means to "fake" a Channel input (and output) between the Main (Top-level) VI and the multiple Asynchronous Clones.  The Main can use the Queue to "fake" a Channel Input to the Clone's CMH, and the Clones can use a Queue to send (Channel) Messages back to the Main.

 

Bob Schor

0 Kudos
Message 6 of 6
(582 Views)