Jef! Posted March 9, 2018 Share Posted March 9, 2018 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! Quote Link to comment Share on other sites More sharing options...
Grrr Posted March 9, 2018 Share Posted March 9, 2018 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. Quote Link to comment Share on other sites More sharing options...
Jef! Posted March 14, 2018 Author Share Posted March 14, 2018 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 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. Quote Link to comment Share on other sites More sharing options...
Grrr Posted March 14, 2018 Share Posted March 14, 2018 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. The second option has a debugging distadvantage due Lee's opinion. Quote Link to comment Share on other sites More sharing options...
Jef! Posted March 23, 2018 Author Share Posted March 23, 2018 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! Cheers Quote Link to comment Share on other sites More sharing options...
Grrr Posted March 25, 2018 Share Posted March 25, 2018 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! 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. Quote Link to comment Share on other sites More sharing options...
Jef! Posted March 26, 2018 Author Share Posted March 26, 2018 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 Cheers! Quote Link to comment Share on other sites More sharing options...
Grrr Posted March 26, 2018 Share Posted March 26, 2018 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 Cheers! Woops, didn't intended to switch on error-handling discussion! Now I realise. 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! ...and thanks for the invitement, Jef! Quote Link to comment Share on other sites More sharing options...
Jef! Posted March 27, 2018 Author Share Posted March 27, 2018 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 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.