vlax获取或创建对象unex
也许有些人会对我的发现感兴趣。我在批处理和循环中大量使用了vlax get或create object,在深入研究后发现了一些意想不到的事情,搜索了为什么执行会随着时间的推移而减慢(从每次程序迭代约0.8秒到几分钟内每次迭代约3秒以上,通过关闭并重新启动cad返回“正常”)。
这是我发现的。。。预期行为:
根据启动的应用程序,下面是一个不太符合预期的行为示例
正如您所见,每个调用都会创建一个新句柄,这当然会影响性能,因为它们都保持打开状态,除非绑定到变量并单独显式释放。。。
坏坏坏,但很高兴知道!
祝大家周末愉快! 是的,我们必须非常小心错误捕捉。。。
通过获得大约5倍的excel应用程序(在VLIDE的控制台中进行实验和转储),我体验到了这一点。
在下一个ACAD会话中,这5个excel实例一次性显示。
是的,脚本代码行为可能取决于应用程序是否已经启动。
顺便说一句,即使在一个点上,也仅仅从(vlax-object-released-p o)评估中得到了一个错误(并且检查(eq’VLA-object(type o))是真的……)。
所以直到那时,vl总是捕捉错误捕捉,除非我试图跟踪错误。
但这就是Lisp程序巨人教给我们的。。与他们的编码。 这是假设的(就像在我的excel预期行为中,你知道,“获取或创建”似乎是不言而喻的。)
..我通常使用错误捕捉来捕捉代码中的错误,而不是Adsk函数中的错误
我最终制作了自己的get或create函数。下面是:
-每个句柄在主程序中需要多个变量
-这个变量就像我的get或create函数的“全局”变量,这是一个用那个古老的vlide管理的pita。。。
-在var超出范围之前,不要忘记在主程序中发布
-最后,在主功能中需要完美的错误捕捉,以释放句柄,以防用户点击escape。
是的,从不打扰tho(总是使用vlax获取或创建对象)
我想我将来会用这个做实验。
我考虑了“vlax get or create object”的替代方案,我想到的最接近的是vlax get object和vlax create object中的vl-some。
但是你可以用这样的方法来确定哪个函数成功了:
(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
)
)
所以它会返回这样的结果:
(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
我并不真正了解你在追求什么,但我看到了3种不同的错误捕获/处理选项
[列表]
[*]*错误*
[*]vl全包适用
[*]带有vlr LISP的反应堆取消/结束vlr命令取消/结束/失败
[/列表]
是的,第三个选项看起来没用,但嘿,它仍然是一个选项。
由于李的观点,第二种选择有一个优势。 抱歉耽搁了,我一直很忙。
我也是,我总是使用vlax获取或创建对象,我不知道你的意思。。。(或理解)
问题是,当多个vlax get或create objects调用每次发送不同的句柄时,vlax get object返回nil。。。
如果可行的话,vl-some可能是一种合适的方法,即使我不明白你为什么要费心建立assoc列表,而不是仅仅按照这些思路去做
(vl-some '(lambda (func / ) ((eval func) "Excel.Application"))
'(vlax-get-object
vlax-create-object
)
)
)
(这在excel中效果很好,但由于简单使用vlax get或create object仍然显得有些过头了)
在我采取的方法中,当使用escape时,我必须使用*错误*陷阱来释放句柄。在没有深入思考的情况下,我不认为vl-catch-all应用程序有什么用处,至于使用reactor,即使我对lisp有很好的理解,我必须承认,即使我尝试了,我也从来没有真正想过要使用reactor。也许我太“视觉化”了,以至于无法理解一个我看不见的概念。对任何掌握反应堆的人都致敬!
李的观点有什么不利之处吗?当一个人的意见影响结果时,这表明这个人有多好!
干杯
我使用assoc list是因为我认为您可能需要确定应用程序对象是已获取(get)还是已创建。
我只会在#main函数中使用*error*,除非我已经考虑了在子对象中可能出现的所有错误。
刚刚提到的反应堆,因为它们是一种可能的选择——尽管可能效率太低,太复杂了。
我对反应堆的总体看法是,只有在被迫使用时才使用它们。
杰夫,这里的关键词是调试缺点!
根据我的经验写作:
看见当您开始对某些对象编写太深的脚本并使用方法时,您不确定是否传递了正确的(类型/数量)参数。
假设代码中有15行用于访问对象和调用从未使用过的方法。
您运行lisp,收到一个错误,因此开始跟踪它。
两种错误处理程序的要点都是:*error*和vl catch all apply是不惜一切代价释放对象(因此从技术上讲,它们具有相同的目的),
然而,不同之处在于*error*将在准确的失败计算时中断,而使用vl catch all apply时,代码将“无声”关闭
在这两种情况下,您都可以读取错误消息,但至少在调试时,这对我来说还不够-我希望看到代码中断的确切行(因此使用*error*)。
但在我完成编写和测试同一个子对象之后,我从*error*切换到vl catch all apply错误处理(如果我必须再次调试它,则反之亦然)。
因此,了解两者之间的区别:
我想说明我完成的脚本对象子操作中所有可能的已知错误,并强制它们在不出错的情况下运行
而我的#主函数或我在测试中使用的子函数会出错。
有些人可能不同意我的观点,但如果一个人使用带有10个子操作的#main函数,
第二个子对象在某些计算机上出现某些(非致命)错误时中断,因此停止了总体评估-因此总体#main没有做任何事情。
顺便说一句,你可以在论坛上找到李对vl catch all apply的看法(这里:这只是他评论给我的印象)。
你可能知道这一切-我只是把这篇文章留给论坛档案。
很抱歉没有回答您的主要“vlax获取或创建对象意外行为”问题(这对我来说也是一件坏事)。
干杯 以下是vlax get或create object的帮助定义:返回应用程序对象的运行实例,或者如果应用程序当前未在if语句旁边运行,则创建新实例(如果应用程序在第一次调用vlax get或create object时不存在/未安装,则为陷阱),它*不*需要任何“错误陷阱”。连续调用(如果调用的应用程序未关闭)应返回相同的句柄IMO。
... ... 我不知道你为什么为没有回答我的主要问题而道歉,因为一开始没有问题。我发现在我的程序中,vlax get或create object的行为出乎意料,我只是想分享我的发现。你似乎系统地曲解了我在这条帖子中的所有帖子,这真让我抓狂。为了娱乐起见,我请你们从头开始再仔细阅读一遍。爆米花和啤酒我请客
干杯
Woops,无意开启错误处理讨论!现在我意识到了。
我的大脑是这样运作的:它试图解决一个问题,在思考的同时产生子问题和想法,从而产生更多的子问题和想法。
虽然我觉得这条帖子很有趣,真的很想听听别人的话!
...谢谢你的邀请,杰夫! 首先解决问题并预见所有子问题,这对编程爱好者来说是一个相当有趣的挑战。即使讨论转移了,也不用担心;无论有没有爆米花,和你聊天总是很愉快
页:
[1]