Jump to content

Calling a dynamically dispatched VI asynchronously


Recommended Posts

I'm trying to reinvent a framework using GOOP, and I've hit a brick wall. I have a member VI that needs to be dynamically dispatched. The caveat is I'd like to call said method asynchronously (not waiting for it to return).

Now I see a few problems with this given my knowledge of how dynamic dispatches and VI server work, but the first one is the most general. How do you invoke a dynamically dispatched VI asynchronously? I've tried my usual way (read: only way of which I'm aware) of opening a VI reference, setting a control value, and invoking it:

post-11742-1224126314.png?width=400

I expected an error here, and sure enough, LabVIEW doesn't disappoint:

Error 1000 occurred at Invoke Node in Test.vi

Possible reason(s):

LabVIEW: The VI is not in a state compatible with this operation.

Method Name: Run VI

VI Path: C:\Users\michael\Desktop\Asychronous Dynamic Dispatch\Base\Foo.vi

Now I expected an error to arise from the polymorphic nature of object wires...the whole idea of the dispatch is to determine which VI of a given interface to invoke at runtime, and I'm handing LV a reference to a specific implementation and asking it to do its thing. Don't know if that's related to the error at hand, but in the end it didn't surprise me. And this is as far as I've gotten...I keep coming back to the same problem of being unable to define which method is going to be called at design time, yet VI Server requiring a specific reference. Anyone know a way to deal with this?

Regards,

-Michael

Link to comment

I'm a bit short on time now and haven't really given any thought on your description and if it should work or not that way.

But here's what I do in my code and this works like a charm..

post-906-1224148810.png?width=400

Thread.vi is in my case a private method and thus not dynamic dispatch, but it in turn calls dynamic dispatch methods on the DAQ class which are overriden in the child classes. I think this should do the trick in your case also.

Link to comment

QUOTE (MJE @ Oct 16 2008, 05:29 AM)

I'm trying to reinvent a framework using GOOP, and I've hit a brick wall. I have a member VI that needs to be dynamically dispatched. The caveat is I'd like to call said method asynchronously (not waiting for it to return).

Now I see a few problems with this given my knowledge of how dynamic dispatches and VI server work, but the first one is the most general. How do you invoke a dynamically dispatched VI asynchronously? I've tried my usual way (read: only way of which I'm aware) of opening a VI reference, setting a control value, and invoking it:

http://lavag.org/old_files/monthly_10_2008/post-11742-1224126314.png' target="_blank">post-11742-1224126314.png?width=400

I expected an error here, and sure enough, LabVIEW doesn't disappoint:

Error 1000 occurred at Invoke Node in Test.vi

Possible reason(s):

LabVIEW: The VI is not in a state compatible with this operation.

Method Name: Run VI

VI Path: C:\Users\michael\Desktop\Asychronous Dynamic Dispatch\Base\Foo.vi

Now I expected an error to arise from the polymorphic nature of object wires...the whole idea of the dispatch is to determine which VI of a given interface to invoke at runtime, and I'm handing LV a reference to a specific implementation and asking it to do its thing. Don't know if that's related to the error at hand, but in the end it didn't surprise me. And this is as far as I've gotten...I keep coming back to the same problem of being unable to define which method is going to be called at design time, yet VI Server requiring a specific reference. Anyone know a way to deal with this?

Regards,

-Michael

You can launch the VI and then send the actual object via user event, queue or notifier. The launched VI waits for this information (You can pass the event refnum or further via VI server before running it) and then launches the base class of the Dynamic dispatch VI which will retain the "dynamic dispatch" part.

This way you don't have to go via Variant.

So what I'm saying is that the code for launching the VI without waiting belongs IN the class. That way you should be able to do what you are looking for without sacrificing the automatic dynamic dispatch handling.

Shane.

Link to comment

Hi Michael,

I could not reproduce the error you get (I'm using LV 8.6). I'm not sure if the version makes the difference, but anyway, the dynamic dispatch didn't work.

I created A & B (B inherited from A) and the VI dynamically called was always A, whatever I did. As you said, I kind of expected it... but I didn't get the errors you mentioned. After all, B object can propagate on A-type wire.

I always got the result expected if A:Calculate was called. So yes, it works with static dispatch... but not dynamical. I'm sure AQ will step in to give the exact reason why it doesn't (or maybe shouldn't ever) work. ;)

QUOTE (shoneill @ Oct 16 2008, 05:35 AM)

You can launch the VI and then send the actual object via user event, queue or notifier. The launched VI waits for this information (You can pass the event refnum or further via VI server before running it) and then launches the base class of the Dynamic dispatch VI which will retain the "dynamic dispatch" part.

This way you don't have to go via Variant.

So what I'm saying is that the code for launching the VI without waiting belongs IN the class. That way you should be able to do what you are looking for without sacrificing the automatic dynamic dispatch handling.

Shane.

Hi Shane,

I don't understand how you will know which instance to call even by wrapping the object in a queue/notifier/user event. If we don't know yet which VI will be called (parent or child), how do you unwrap from the queue when the code is dynamically called? The way I imagine it (not tried this yet), I don't know how I can avoid ending up with the parent object type.

Link to comment

QUOTE (normandinf @ Oct 16 2008, 03:47 PM)

Hi Shane,

I don't understand how you will know which instance to call even by wrapping the object in a queue/notifier/user event. If we don't know yet which VI will be called (parent or child), how do you unwrap from the queue when the code is dynamically called? The way I imagine it (not tried this yet), I don't know how I can avoid ending up with the parent object type.

Well I was under the impression that you don't NEED to know the internal class representation. Even casting all objects in an array to a base class will still call the CORRECT dynamic dispatch VI when using those objects. So just casting an object as a parent class does not make it suddenly call the parent version of a dynamic dispatch VI. It will still call the correct dynamic dispatch VI. The QUEUE/notifier/Event simply avoids variant which could otherwise be problematic.

As AQ has already stated, a single VI with a dynamic dispatch call will do the trick. My idea was to have this VI AQ is referring to within the class, in essence moving the "dynamic dispatch" part up one level.

Getting the exact VI refnum might be problematic though, so AQ's solution gets around that.

Shane.

Shane.

Link to comment

QUOTE (shoneill @ Oct 16 2008, 10:46 AM)

Well I was under the impression that you don't NEED to know the internal class representation. Even casting all objects in an array to a base class will still call the CORRECT dynamic dispatch VI when using those objects. So just casting an object as a parent class does not make it suddenly call the parent version of a dynamic dispatch VI. It will still call the correct dynamic dispatch VI. The QUEUE/notifier/Event simply avoids variant which could otherwise be problematic.

As AQ has already stated, a single VI with a dynamic dispatch call will do the trick. My idea was to have this VI AQ is referring to within the class, in essence moving the "dynamic dispatch" part up one level.

Getting the exact VI refnum might be problematic though, so AQ's solution gets around that.

Shane.

Shane.

Now I see. I didn't get what you were explaining at first. Sorry for the confusion.

Link to comment

QUOTE (normandinf @ Oct 16 2008, 05:20 PM)

Now I see. I didn't get what you were explaining at first. Sorry for the confusion.

Well since I was (supposedly) the one doing the explaining, shouldn't the apology be from me?

Just do whatever AQ says (or writes).

Where's the "Set current value to default" for these Forums :worship:

Shane.

Ps Forgot the actual apology.... Sorry (for forgetting). Sorry (For confusion). :rolleyes:

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.