LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Error 1 Generate user event

Hi everyone,

I'm working on an application based on LabVIEW's Actor Framework for test and calibration automation.
The system is composed of several modules (nested actors) that control physical devices and process raw data. These actors communicate with the root actor (Test Actor), which provides a User Interface that relies on User Events for data display.

I've been experiencing some issues when generating these User Events — specifically error 1 when updating UI data. Interestingly, this error only occurs the first time I run the application; subsequent executions do not show the problem.

Initially, I suspected a race condition where Generate User Event was being called before the User Event itself was created. However, after debugging, I confirmed that the error still appears even when the User Event Refnum is already valid.

 

As shown in the first image, before executing Generate User Event, both the User Event Refnum and the Event Data are correctly set.

 

Debugging 1Debugging 1

 

After attempting to generate the User Event, the following error message appears:

 

Debugging 2Debugging 2

 

Thanks in advance!

0 Kudos
Message 1 of 13
(214 Views)

Where in the structure do you create the UE ? 

How do you store the UE reference to the Actor? 

 

Message 2 of 13
(200 Views)

A user event is a LabVIEW refnum. LabVIEW refnums are automatically collected at the moment the top level VI in whose hierarchy the refnum was created goes idle (finishes execution). If you run the VI that contains the Create User Event call on its own, this VI is the top level VI and the user event refnum is immediately destroyed when your VI ends. The numeric value for the refnum is simply a reference (not a real pointer) that tells LabVIEW how to find the actual object in its own internal registry. Once the object is destroyed, that refnum value "points" to nothing, no matter that its numeric value remains. LabVIEW as a by value language can't go and change the actual refnum value elsewhere, only explicit dataflow can change it.

 

But the logic goes even further. If you create an actor (or a DQMH message handler) it starts its own actor/daemon/engine as an asynchronous top level VI that has no owner. Any refnum created within this asynchronous top level VI has its lifecycle determined by the lifetime of this top level VI. Once your actor/engine stops executing, all the refnums created within its context are automagically collected and destroyed. The fact that you stored the refnum somewhere and try to use it from a different place has no meaning. The object this refnum references has been destroyed and you correctly receive error 1 from any function trying to access that object, since it effectively has been destroyed.

 

If you want to work with refnums across actors, you have to make sure to create the refnum in the actor that survives any use of that refnum anywhere else, or make sure to keep the creating actor alive until you do not need the refnum anymore anywhere. Some Actor Frameworks contain an actual separate actor that is kept alive for the duration of the application for nothing else than delegation of creating a specific LabVIEW refnum type just for this single reason. Theoretically it would have been possible to allow at the creation of a refnum object to decide if the refnum lifecycle should be tied to the top level VI or rather only the application lifecycle. The underlaying Magic Cookie manager that is used for refnums has that capability, but it was decided that this was a to strong burden for most LabVIEW developers and that option has not been made available on the diagram level. I think it's a valid decision for most casual LabVIEW developers, a problem for casual developers moving into more intermediate application design, and a minor annoyance for most advanced developers.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 3 of 13
(183 Views)

Is that UE reference from the root actor and you are using it in the nested actors? In actor framework, you should use messages to send data to other actors. Have the nested actors send messages and call Generate User Event when handling the message in the root actor.

 

For the user event creation, I usually use Pre-Launch Init or a SubVI in Actor Core that gets called before calling Actor Core parent.

Message 4 of 13
(169 Views)
The User Event is both created and stored inside the actor. These User Events are used only to notify the actor’s Front Panel (overridden in Actor Core) about changes in the application state, so they are not shared between actors.
I've seen this approach (using a User Event to update the actor’s front panel) in the Actor Framework Fundamentals project, so I assumed it was the correct method.
0 Kudos
Message 5 of 13
(113 Views)

This is the Test Actor Library. There may be some missing files, but I think it's just enough for this

0 Kudos
Message 6 of 13
(110 Views)

Thanks for sharing the code. 

 

But there is no call to "Create User Event". 

Where do you create the User Event ? 

Message 7 of 13
(82 Views)

You have the same reference number in both pictures, so it looks like you're using an old ref?

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
Message 8 of 13
(73 Views)
The user event is created in the "New Test" method. I'm using it as a constructor method, so it's the way I create a new instance of the class.
I know that a constructor method is not strictly necessary in LabVIEW, but it's a good way to keep the code clean.
0 Kudos
Message 9 of 13
(71 Views)

@Yamaeda  ha escrito:

You have the same reference number in both pictures, so it looks like you're using an old ref?


Yes, both pictures are captured at the same moment, before and after generating the User Event, so should be the same

0 Kudos
Message 10 of 13
(69 Views)