LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
JohanHoltby

Destructor LabVIEW

Status: Declined

Any idea that has received less than 4 kudos within 4 years after posting will be automatically declined.

It would be nice to have a callback to register when a VI is unloaded from memory.

I normaly use FGV pattern to encapsulate my instruments. I would be neet to register a "close" VI when you initilize the FGV VI and then when the FGV is unloaded the close VI closes the refereances (and transform the instrument to a safe state).

 

To conclude I want a similar way to  C++ destructor.

21 Comments
AristosQueue (NI)
NI Employee (retired)

Please note: He's asking for a destructor on a running VI, not a destructor on an LVOOP object. Processes and references have meaningful lifetime in a dataflow language; data does not. That's what makes this a valid request compared to the other Idea Exchange requests for destructors on objects.

 

I just figured I'd post this comment to head off any "but you said..." discussion about object destructors. 🙂

JohanHoltby
Member

Happy to here that and especially from some one doing LVOOP. Since that have been uncharted territories for me.

AristosQueue (NI)
NI Employee (retired)

Now, Jonan, there is an alternative approach to achieve your encapsulation goals. Can create a VI that does destructor work in its own code, obviously, it just needs to know when to stop. So when you start your process VI running, use Start Asynch Call By Ref and give it a refnum (I prefer the queue refs for various reasons) to use to communicate with it. You can enqueue data messages to make it do work. So rather that call it as a subVI and then need to check for "on unload" to do a destructor, it is just always available. There's a separate "stop" message that you enqueue to tell it to stop, and that makes it do its shutdown code. This pattern works quite well for a lot of apps. It keeps the functionality entirely encapsulated within the subroutine.

JohanHoltby
Member

Intresting. But I don't understand the upside compared to a FGV having a strict type def enum handling the different task. No need to Instantiate since i do lazy instantiazion like the singelton pattern (your aproce seams to require instantiation). Pleas see this as a curius question as it's intended. 🙂 I understnad you have an upside in mind.

AristosQueue (NI)
NI Employee (retired)

With an FGV, the VI is not continuously running. The FGV does whatever it does when it is called and then returns to its caller. From its internal point of view, it is done everytime it finishes an instruction.

 

You give that FGV different instructions by using some set of parameters -- an enum is fine.

 

What I'm suggesting is you turn your FGV into an asynchronously running VI that listens on a queue for those enum values. It does what it does and then it goes back to listening on the queue. It isn't taking up CPU, but it also isn't finished executing. Only when you tell it "hey, you're actually done" then it does its cleanup work as it exits.

 

Make sense?

JohanHoltby
Member
Thank you for your explanation now I understand your implementation.
 
So if I understand correctly the benefit is that we have a responsive VI ruining asynchronously. This makes it possible to monitor and run test steps in parallel e.g. verify that a voltage level never drops below 4V during the entire execution of the test period when many other test steps are executing in test stand.
 
But if we also still wrap the reference using a FGV VI we can keep the lazy initiation.
 
Seams like an interesting approach I have not thought about even if it still don't encapsulate the clean up to prevent the Test stand developer to don't have to bother about closing references.
 
I really hope this feature gets added since it should not be to much work since they most probably only have to make a internal callback visible in LabVIEW. 

 

AristosQueue (NI)
NI Employee (retired)

It's actually a lot of work, and not necessarily doable. Think about it -- you want to put code on the block diagram of a VI that only executes when the VI is done running (i.e. all of its callers have gone idle and it won't be called again). That's a contradiction in terms. So it raises ideas like a zoned off structure on the diagram that only executes when the VI is called by LV internally to tell it "you're done" OR a completely separate block diagram... the separate diagram may be needed because it might have its own conpane for information from the caller. But that raises issues of getting information from the main diagram to the other diagram, i.e., the info the user needs to do the destruction work.

 

There's a lot of zaniness that can ensue if you walk down that road far enough. Dataflow really REALLY doesn't like you to even think in those terms. It hates designs that have side effects like that, and will fight you every step of the way, whether you're a regular developer or a language designer like me. And sometimes we just say, "That's a concept that we just don't see fitting into LV," like we did with destructors on LV classes and do something entirely different that gets us there.

 

I say all this because although I kudos'd the idea (because I have wanted it myself in the past), the right answer might be, "Strengthen the support for actor-oriented programming in G." That's the hypothesis I maintain most often these days when questions of lifetime management come up. (Actor-oriented programming is that asynchronous-process-listens-for-message pattern that I was discussing.)

JohanHoltby
Member

I get your point. What I did intend was to have two VI's (one FGV wrapper and the actual asynchronous VI) and I agree: this will not solve in any way the closing problems as you stated.

 

However the asynchronous parallel structure you describe is something that I have implemented in C# in other test systems when there is things which can be done in parallel.

This is a huge time saver and I'm thankful that you did bring the suggested implementation to my knowledge even if it's not really a solution the the problem since we don't know when the VI is closing.

 

My dream is to make a VI which the test stand developer calls and it never crashes no matter what order they calls the different FGV states. If however the user do something wrong the VI just politely informs the user about the contradiction using internal error handling and sends the error out to the developer. E.g. sends a request for data before generating the data.

JohanHoltby
Member

Might have realized a solution. If we leave a open VI in a FGV the reference is open until LabVIEW closes will this be a problem since LabVIEW closes all references for us when  LabVIEW closes.

So if I understand correctly the worries about leaving open references is no problem more that it might start to allocate more and more memory  but since we do reuse the reference using the FGV that is not a problem. Is this correct?

AristosQueue (NI)
NI Employee (retired)

LabVIEW closes a reference automatically when the top-level VI that allocated the reference goes idle.

As long as the top-most VI never goes idle, the reference stays open.

 

You are correct that there's no problem with leaving a reference open if you are coming back to reuse it.