我们有一个带Oracle 11g后端的旧版PowerBuilder 12.1 Classic应用程序,并且在生产中遇到了性能问题,我们无法在测试环境中重现该问题。
有问题的窗口具有共享的网格/自由格式的DataWindows和用于打开其他响应窗口的按钮,这些窗口在关闭时会导致重新检索网格。
网格后面有一个非常昂贵的查询,几列从函数调用中接收到它们的值,其中包含一些非常复杂的SQL,但是即使在生产中,它仍然可以在几秒钟内运行。
错误发生时唯一的一致性是,如果它们试图快速导航到其他窗口,则似乎更有可能。 打开所述窗口的按钮假定已将某个实例变量设置为网格中焦点所在行的适当值。 但是,在这种情况下,即使看起来好像发生了行焦点更改,也尚未设置实例变量。 这导致了原本不可能的空引用异常。
最终用户的网络连接通常都很缓慢,其硬件功能也不比我们的硬件低。 我想怪网络,但是我试图通过故意降低SQL的速度在开发过程中重现这一点,以便我可以尝试单击按钮,但是一切都按我的预期进行了:单击按钮直到检索和执行之后才发生其他所有事件都结束了。
我的直觉告诉我,由于某些原因,事情在应有的时候并没有同步运行,而我能想象的唯一因素是SQL的速度,无论是查询速度慢还是网络速度慢,但是当我尝试重现时效果依旧依旧发生。 唯一可疑的代码是数据ue_post_rfc
从rowfocuschanged
发布了一个名为ue_post_rfc
的用户事件,并且此事件执行Yield()
。 ue_post_rfc
是代码去的地方,而不是rowfocuschanged
。
即使在人为降低SQL速度的情况下, Yield()
是否有任何方式会导致这些问题,而不会在测试环境中表现出来呢?
尽管您的消息可能无法提供足够的信息来为您提供解决问题的方法,但它的确给了我一些提示,提示我在PowerBuilder系统中经常会遇到难以诊断的故障。
开发事件的顺序是这样的
我建议摆脱这个问题(如果这是您的问题)是:
祝好运,
特里
PS:这是您问题中的两句话,使我想到了Yield()(不是我不喜欢跳过Yield() 笑容的机会)
错误发生时唯一的一致性是,如果它们试图快速导航到其他窗口,则似乎更有可能。
当用户尝试非常快速地启动(例如说)两个动作时,可以看到这一点。 如果第一个动作的脚本包含Yield(),则第二个动作的脚本将在第一个动作完成之前开始和结束。 对于用户操作的任何组合(例如按钮单击,菜单单击,选项卡,窗口关闭...),都是如此,您编写的代码有可能在Yield()完成后不再存在该窗口,对吗? ,请加入99%的代码,这些代码将对Yield()进行编码,不要这样做并危险地生活)和系统事件(例如GetFocus,Deactivate,Timer)
我的直觉告诉我,由于某些原因,事情在应有的时候并没有同步运行
你是对的。 PowerBuilder(除非您强制执行)是同步运行的。 但是,如果一个事件在另一个事件完成之前开始(请参见上文),那么您将获得看起来像异步行为的行为。
您所说的内容没有定论,但您确实询问过Yield()。 可以确定这一点的真正方法是,如果您可以使用PBDEBUG跟踪来重现它; 您会看到哪些事件令您感到惊讶。 但是,PBDEBUG减慢速度的数量会影响事件序列和排队,这可能会或可能不会有帮助。