Jump to content

vlax-get-or-create-object unexpected behavior


Jef!

Recommended Posts

Maybe some could be interested in my findings.

I made extensive use of vlax-get-or-create-object in batch and loops, and noticed something unexpected after digging in, searching why the execution was slowing over time (from ~0.8 sec per program iteration to ~3+ sec per iteration within few minutes, going back to "normal" by closing and restarting cad).

 

Here's what I found out... expected behavior:

Command: (vlax-get-or-create-object "excel.Application")

#

Command: (vlax-get-or-create-object "excel.Application")

#

Command: (vlax-get-or-create-object "excel.Application")

#

 

Depending on the app launched, here's an example of a less expected behavior

Command: (vlax-get-or-create-object "SldWorks.Application.21")

#

Command: (vlax-get-or-create-object "SldWorks.Application.21")

#

Command: (vlax-get-or-create-object "SldWorks.Application.21")

#

As you can see every call creates a new handle, which of course hinders performance as they all remain opened unless bound to a variable and explicitly released individually...

 

Bad bad bad, but good to know!

have a nice week end folks!

Link to comment
Share on other sites

Yup, one must be very careful with the error-trapping there...

Experienced myself by obtaining like 5 times the excel application (while experimenting and dumping in VLIDE's console).

In the next ACAD session these 5 instances of excel displayed in one go.

 

And yeah, the scripting code behaviour may depend if the app is already launched.

 

BTW even at one point got an error just from the (vlax-object-released-p o) evaluation (and the check (eq 'VLA-OBJECT (type o)) was true..).

so till then always vl-catch-error-trapping, unless I'm trying to trace the error.

 

But thats what the LISP giants taught us.. with their coding.

Link to comment
Share on other sites

And yeah, the scripting code behaviour may depend if the app is already launched.

it is supposed (like in my excel expected behavior, you know, "get-or-create" seems rather self explanatory boolean imo.)

..I usually use error trapping to catch errors in my code, not in Adsk functions :D

 

I ended up making my own get-or-create function. The down sides are:

-need for one more variable in the main program per handle

-that variable is like a "global" var to my get-or-create function, which is a pita to manage with that archaic vlide...

-don't forget to release in main program before var becomes out of scope

-and finally needs flawless error trapping in the main function to release the handles as well in case user hits escape.

Link to comment
Share on other sites

it is supposed (like in my excel expected behavior, you know, "get-or-create" seems rather self explanatory boolean imo.)

 

Yea, never bothered tho (always used vlax-get-or-create-object)

Guess I'll experiment with this in the future.

 

I ended up making my own get-or-create function. The down sides are:

-need for one more variable in the main program per handle

-that variable is like a "global" var to my get-or-create function, which is a pita to manage with that archaic vlide...

-don't forget to release in main program before var becomes out of scope

-and finally needs flawless error trapping in the main function to release the handles as well in case user hits escape.

 

I thought about alternative for 'vlax-get-or-create-object', well closest that comes up to my mind is vl-some within vlax-get-object and vlax-create-object.

But you could use something like this to determine which function succeeded:

(vl-some '(lambda (a b / tmp) (if (setq tmp ((eval b) "Excel.Application")) (cons a tmp)))
 '(1 2 3)
 '(vlax-get-object
   vlax-create-object
   vlax-get-or-create-object
 )
)

 

So it would return something like this:

(1 . <Excel Application Object>) ; obtained with vlax-get-object
(2 . <Excel Application Object>) ; obtained with vlax-create-object
(3 . <Excel Application Object>) ; obtained with vlax-get-or-create-object

 

Not really into what you are after, but I see 3 different options for the error-trapping/handling

  • *error*
  • vl-catch-all-apply
  • reactor with vlr-LispCancelled/Ended vlr-CommandCancelled/Ended/Failed

 

Yeah, the 3rd option looks useless but hey its still an option. :D

The second option has a debugging distadvantage due Lee's opinion.

Link to comment
Share on other sites

  • 2 weeks later...

Sorry for the delay, been busy.

 

Yea, never bothered tho (always used vlax-get-or-create-object)

me too I always use vlax-get-or-create-object, i'm not sure what you meant...(or understood)

 

I thought about alternative for 'vlax-get-or-create-object', well closest that comes up to my mind is vl-some within vlax-get-object and vlax-create-object.

 

The thing is when multiple vlax-get-or-create-objects calls send different handles every time, vlax-get-object returns nil...

Command: (vlax-create-object "SldWorks.Application.21")

#

Command: (vlax-get-object "SldWorks.Application.21")

nil

 

If it would work, vl-some could be a suitable approach, even tho I don't understand why you bothered building assoc lists instead of just going with something along these lines

(vl-some '(lambda (func / ) ((eval func) "Excel.Application"))
 '(vlax-get-object
   vlax-create-object
 )
)
)

(which works well with excel, but since plain use of vlax-get-or-create-object works still seems overkill)

 

Not really into what you are after, but I see 3 different options for the error-trapping/handling

  • *error*
  • vl-catch-all-apply
  • reactor with vlr-LispCancelled/Ended vlr-CommandCancelled/Ended/Failed

with the approach i took i had to use *error* trapping to release handles when escape is used. Without really thinking in depth I don't see how vl-catch-all-apply could be useful, and as for using reactors, even if I have good understanding of lisp, I must admit that even if I tried I never really managed to wrap my head around reactors. Maybe i'm too "visual" to grasp a concept that I cannot see. Hat's off to anyone mastering reactors! :)

 

The second option has a debugging distadvantage due Lee's opinion.
Has disavantages due to Lee's opinion? When someone's opinion affect the outcome, it shows how good that person is! :D

 

Cheers :)

Link to comment
Share on other sites

If it would work, vl-some could be a suitable approach, even tho I don't understand why you bothered building assoc lists instead of just going with something along these lines

(vl-some '(lambda (func / ) ((eval func) "Excel.Application"))
 '(vlax-get-object
   vlax-create-object
 )
)
)

(which works well with excel, but since plain use of vlax-get-or-create-object works still seems overkill)

 

I used assoc list because I thought you might want to determine if the application object was obtained(get) or created.

 

 

with the approach i took i had to use *error* trapping to release handles when escape is used. Without really thinking in depth I don't see how vl-catch-all-apply could be useful, and as for using reactors, even if I have good understanding of lisp, I must admit that even if I tried I never really managed to wrap my head around reactors. Maybe i'm too "visual" to grasp a concept that I cannot see. Hat's off to anyone mastering reactors! :)

 

I'd use *error* only in my #main function, unless I've accounted all the possible errors I could get in my subfoo.

Just mentioned reactors, because they are a possible option - altho maybe too inefficient and complex.

My overall opinion about reactors is to use them only when you are forced to.

 

 

Has disavantages due to Lee's opinion? When someone's opinion affect the outcome, it shows how good that person is! :D

 

Jef, the keyword here is debugging disadvantages! :)

 

Writing from my experience:

See.. when you start scripting too deep into some objects and use methods, where you are unsure if you passed the right (type/amount) arguments.

And say there are 15 lines in your code that are used to access objects, and invoke methods you never used.

You run your lisp and you recieve an error, so you start tracing it.

The point of both error handlers: *error* and vl-catch-all-apply, is to release the objects at all cost (so technically they have the same purpose),

However the difference is that *error* will break at the exact failed evaluation, while with vl-catch-all-apply the code will go-off 'silently'

In both cases you can read the error-message, but atleast when I'm debugging this is not enough for me - I want to see the exact line where the code breaks (hence use *error*).

But after I completed writing & testing that same subfoo, I switch from *error* to vl-catch-all-apply error-handling (and vice-versa if I have to debug it again).

 

So knowing the difference between the two:

I would want to account all the possible known errors in my finished scripting-objects subfoos, and force them to run without breaking at error

while my #main function or the subfunctions that I've put on the test to break at error.

 

Some guys might disagree with me, but say one uses a #main function with 10 subfoos,

the 2nd subfoo breaks at some (non-fatal)error on certain computers, hence stops the overall evaluation - so the overall #main isn't doing anything.

 

BTW, you could trace Lee's opinion(s) about vl-catch-all-apply here on the forum (here: thats just my impression from his comments).

 

You probably know all of this - I'm just leaving this post for the forum archive.

Sorry for not answering to your main 'vlax-get-or-create-object unexpected behavior' question (thats a black matter for me aswell).

Cheers. :)

Link to comment
Share on other sites

Here's the help definition of vlax-get-or-create-object: Returns a running instance of an application object, or creates a new instance if the application is not currently running Beside an IF statement (to trap if the app doesn't exist/isn't installed the first time vlax-get-or-create-object is invoked), it *should not* require any "error trapping". Successive calls (if the invoked app isn't closed) should return the same handle IMO.

 

Sorry for not answering to your main 'vlax-get-or-create-object unexpected behavior' question

... ... I'm not sure why you apologize for not answering my main question, as there was no question to start with. I found that in my program vlax-get-or-create-object behaved unexpectedly and I just wanted to share my findings. It really cracks me up to which extent you seem to have misinterpreted systematically all my posts in this thread. I invite you to carefully read it all again from the beginning, for entertainment sake. Popcorn and beer are on me :D

 

Cheers! :)

Link to comment
Share on other sites

It really cracks me up to which extent you seem to have misinterpreted systematically all my posts in this thread.

I invite you to carefully read it all again from the beginning, for entertainment sake. Popcorn and beer are on me :D

 

Cheers! :)

 

Woops, didn't intended to switch on error-handling discussion! Now I realise. :oops:

My brain functions like this: it tries solving one problem, and while thinking it generates sub-problems and ideas, that generate more sub-problems and ideas.

Although I find this thread interesting and really wanted to hear a word from someone else! :geek:

 

...and thanks for the invitement, Jef! :lol:

Link to comment
Share on other sites

Solving the problem and foresee all the sub problems on the first go, that is quite a fun challenge for programming lovers. Even if the discussion shifted, no worries; it is always nice to chat with you, with or without pop corn :D

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

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.   Restore formatting

  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...