1

Oracle11gバックエンドを備えたレガシーPowerBuilder12.1Classicアプリケーションがあり、テスト環境では再現できない本番環境でのパフォーマンスの問題が発生しています。

問題のウィンドウには、グリッド/フリーフォームのデータウィンドウと他の応答ウィンドウを開くためのボタンがあり、閉じるとグリッドが再取得されます。

グリッドの背後には非常にコストのかかるクエリがあり、いくつかの列は、非常に強力なSQLを含む関数呼び出しから値を受け取りますが、本番環境でも数秒以内に実行されます。

エラーが発生したときの唯一の一貫性は、他のウィンドウにすばやく移動しようとした場合に発生する可能性が高いように見えることです。上記のウィンドウを開くボタンは、特定のインスタンス変数がグリッド内のフォーカスされている行からの適切な値で設定されていることを前提としています。ただし、このシナリオでは、行フォーカスの変更が発生したように見えても、インスタンス変数はまだ設定されていません。これにより、発生してはならないnull参照例外が発生します。

エンドユーザーのネットワーク接続はしばしば低速であり、彼らのハードウェアは私たちよりも能力が劣っていません。ネットワークのせいにしたいのですが、SQLを意図的に遅くしてボタンをクリックできるようにすることで、開発中にこれを自分で再現しようとしましたが、すべてが期待どおりに行われました。ボタンのクリックは、取得してから他のすべてのイベントは終了しました。

私の腸は、何らかの理由で物事が必要なときに同期して実行されていないことを教えてくれます。私が想像できる唯一の要因は、クエリが遅いかネットワークが遅いかにかかわらず、SQLの速度ですが、再現しようとしたときその効果はまだ適切な順序で起こった。唯一の疑わしいコードは、データウィンドウの祖先がue_post_rfcから呼び出されたユーザーイベントを投稿しrowfocuschanged、このイベントがを実行することYield()です。 ue_post_rfcの代わりにコードが入る場所ですrowfocuschanged

Yield()SQLが人為的に遅くなった場合でも、テスト環境に現れることなく、これらの問題を引き起こす方法はありますか?

4

1 に答える 1

1

あなたのメッセージはあなたにあなたの問題を解決するためのレシピを与えるのに十分な情報を与えないかもしれませんが、それは私がPowerBuilderシステムでしばしば見かける診断が難しい失敗の一般的なポイントへのヒントを私に与えます。

開発イベントのシーケンスは次のようになります

  • 開発者は、あるイベントが別のイベントの前に発生することに依存し、多くの場合、インスタンスまたはグローバル変数を介して依存するコードを開発します
    • このイベントシーケンスは開発者が観察したものですが、保証されたシーケンスとして文書化されていません(AcceptText()シーケンスやUpdate()シーケンスが文書化されているように)
    • 私はこれを投稿されたイベントでたくさん見つけます、そして私はポストイベントイベントから投稿されるイベントポストイベントについて話していませんが、 post-ItemChangedpost- GetFocusの間のようです
  • 何かがイベントのシーケンスを変更し、コードを壊します。私が見たものは、イベントの非保証シーケンスを変更します:
    • PowerBuilderのバージョン変更
    • オペレーティングシステムの変更
    • ハードウェアの変更
    • システムリソースに負担をかける他のアプリケーションで実行されているアプリケーション
  • 現在これを解決している人は誰でも、何が起こっているのか、それをどのように処理するのか見当がつかないので、Yield()ステートメントでコードをペッパーし始めます(私は文字通りYield()の横に「私はなぜこれが機能するのかわかりませんが、問題Xを解決します")
    • Yield()を使用すると、メッセージキュー内のすべてのイベントを処理できますが、この開発者は、特定のイベントを1つだけ通過させたいと考えています。
    • また、私のキャリアでよく見られるDO ... LOOP UNTIL(Yield()ではない)は、負荷の高いシステムで無限にループする可能性があることにも注意してください。
  • 何かが起こってイベントシーケンスが再び変更されました
  • これで、Yield()が発生すると、開発者が処理したかったメッセージではなく、処理されるメッセージの異なるシーケンスがキューにあります。
  • 物事は再び失敗し始めます

この問題を取り除くための私のアドバイス(これがあなたの問題である場合)は、次のいずれかです。

  • イベント間の依存関係を取り除く
  • イベントシーケンスの仮定を取り除く
  • イベントシーケンスを自分で管理する

幸運を、

テリー


PSここに、Yield()について考えさせるあなたの質問からの引用がいくつかあります(Yield()の笑顔を飛び越える機会が好きではないというわけではありません)

エラーが発生したときの唯一の一貫性は、他のウィンドウにすばやく移動しようとした場合に発生する可能性が高いように見えることです。

これは、ユーザーが2つのアクション(たとえば)を非常にすばやく開始しようとしたときに見られます。最初のアクションのスクリプトにYield()が含まれている場合、2番目のアクションのスクリプトは、最初のアクションが終了する前に開始と終了の両方を行います。これは、ユーザーアクション(ボタンクリック、メニュークリック、タブ、ウィンドウを閉じるなど)の任意の組み合わせに当てはまります。Yield()が実行された後、ウィンドウがもう存在しない可能性をコーディングしました。そうでない場合は、 、Yield()をコーディングするものの99%に参加し、しないで、危険な状態で生活します)およびシステムイベント(GetFocus、Deactivate、Timerなど)

私の腸は、何らかの理由で物事が必要なときに同期して実行されていないことを教えてくれます

あなたが正しい。PowerBuilderは(強制しない限り)同期して実行されます。ただし、あるイベントが別のイベントが終了する前に開始している場合(上記を参照)、非同期動作のように見える動作が得られます。

あなたが言ったことに決定的なものは何もありませんが、あなたYield()について尋ねました。これを突き止めるための本当にキッカーは、PBDEBUGトレースでこれを再現できるかどうかです。どのイベントがあなたを驚かせているかがわかります。ただし、PBDEBUGの速度が低下する量は、イベントシーケンスとキューイングに影響し、役立つ場合と役に立たない場合があります。

于 2012-08-30T14:13:03.313 に答える