LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Circumvent reference cleanup when VI ends?

Solved!
Go to solution

Here's a somewhat finished chat client/server app I'm working on to test all the features:

Server SideServer SideClient SideClient Side

The Server does not forward received messages back out to other connected clients yet and the client doesn't have read capability yet but every bit of the library is here. Servers spawn instances of the same exact client code that client side connections use. Clients provide an underlying stream object that wrap reading/writing functionality. The idea is to very rarely use this library directly; instead it will have additional layers that fulfill layer 6/7 of the OSI network model for use by applications. (Simple messaging, Serializable object streaming, etc)

 

Still waiting to hear back about being able to post code but at the pace things move here it won't be well into the new year until I hear back Smiley LOL

 

0 Kudos
Message 21 of 24
(698 Views)

@DerrickB wrote:

 The idea is to very rarely use this library directly; instead it will have additional layers ...

 


Hopefully, the added layers will (through specialisation) present a simpler API.  As an exercise, I wrote a Chat implementation in Messenger Library (which is specialised to messaging patterns only). Here's the Server block diagram:

Notification Server.png 

There is a lot going on behind these high-level API calls of course, but it is important that the complexity is abstracted into something simple.

 

Chat Client.png 

 

 

Download All
0 Kudos
Message 22 of 24
(682 Views)

Dear tyk007,

 

I have been trying to understand this lately and my observations agree with your description, with one subtle difference:

 

you say "As far as I am aware LabVIEW clean-ups references automatically when a VI Hierarchy goes idle (as a result of the top-level VI ending)"

 

if the top-level VI is spawned by a "Start Asynchronous Call primitive" the lifetime is not bound to the VI execution lifetime (VI ending) but to the VI reference lifetime. If the VI ends and you don't close the VI reference the references created within the VI hierarchy are not destroyed, they will be as soon as you call the "Close Reference" primitive.

 

I am pretty confident about this as I banged my head for a full this when writing a library adding async call functionality to the actor framework.

 

Cheers

 

Andrea

0 Kudos
Message 23 of 24
(163 Views)

@lsi wrote:

 

if the top-level VI is spawned by a "Start Asynchronous Call primitive" the lifetime is not bound to the VI execution lifetime (VI ending) but to the VI reference lifetime. If the VI ends and you don't close the VI reference the references created within the VI hierarchy are not destroyed, they will be as soon as you call the "Close Reference" primitive.

 

I am pretty confident about this as I banged my head for a full this when writing a library adding async call functionality to the actor framework.


That's quite possible but I never use the Start Async in such a way. Either I'm caching the original refnum from the Open VI refnum and use the Open VI flag 0x08 to spawn a new reentrant instance of the VI on every Async Start or I immediately close the refnum after the Async Start was successful. Anything else only makes the refnum management more complicated.

 

The reason to do the caching is that the Open VI is a blocking operation that runs in the UI thread and that takes some significant time so if you need to instantiate a VI regularly such as an executor in a class for a background processing task. This can add up for larger applications with many such classes. By caching the original refnum and creating a new instance everytime you need one this can speed up starting up such an executor system with many classes quite a bit. 

Rolf Kalbermatter
My Blog
0 Kudos
Message 24 of 24
(153 Views)