事例の背景:
関数全体は、実際にはデータベースからデータを取得し、それをインターフェイス上で再生することです。簡単に言うと、取得するのが文字列データである点を除けば、オンラインでビデオを見たり、音楽を聴いたりするのと似ています。取得するのはファイル データです。全体のデータを 10 個の部分に分割し、10 個のスレッドがデータベースから同時にデータを取得し (同時実行により速度が向上します)、別のスレッドがキューからデータを取得してインターフェイス上で再生することができます。再生の進行状況をドラッグして一時停止したり、再生を再開したり、再生速度を制御したりできます。まあ、この機能は単純そうに見えますが、実行するのは難しくありません。しかし、後にいくつかの問題が発見され、これらの問題を掘り下げていくと、覚えておく価値があると思われることがいくつか見つかりました。
重要なこと:
1. Silverlight バックグラウンド スレッド BackgroundWorker m_GetReplayData= new BackgroundWorker();
2. インターフェイス コントロールへのクロススレッド アクセス、this.Dispatcher.BeginInvoke(/Access インターフェイス UI); 3. JavaScript スタイルの関数ポインター: var ShowSIngleLog = function(){} ; (親ページ上)
4. 子ページは親ページのイベントを登録します: var fatharWindow = window.opener; fatharWindow .ShowSIngleLog =function (){//Play data showTrace()};
5.JavaScript エンジン スレッド、インターフェイス レンダリング スレッド、ブラウザ イベント トリガー スレッド
6。 、すべてが同期されます はい、同時に実行されている 2 つのスレッドはありません
問題:
Silverlight は、インターフェイス データを再生する効果を実現するために、Silverlight スレッドのループを通じて JS メソッドを呼び出します。これは、Silverlight が実行できるのは呼び出しのみであるためです。このページのJSメソッドですが、トラック再生ページはメインページからポップアップするサブページなので、メインページの空の関数ポインタを使用し、サブページは親ページのイベントを登録して目的を達成しますSilverlight によるサブページ メソッドの呼び出し (上記のポイント 3)。慎重な審議と議論の結果、問題がないと判断し、終わってみれば問題はなかった。ローカル テストはすべて数百または数千のデータを使用しましたが、進行状況の停止、一時停止、ドラッグには大きな問題はありませんでした。唯一の問題は、親ページのインターフェイスが少し動かなくなったことです。最初はこの問題に注意してください。テストでは、20,000 個を超えるデータを 5 分間再生した後、トラック再生ページの停止、ドラッグ進行、一時停止、および再生ボタンがすべてフリーズしました。この現象は非常に奇妙で、一度は試験機の問題だと思っていましたが、最終的には大量のデータの問題であることがわかりました。 This.Dispatcher.BeginInvoke(/access インターフェイス UI) は非常に単純で普通の呼び出しのように見えますが、次の 2 つの特徴があります:
1. 非同期である、つまり、調整されてもすぐに実行されない可能性があります。最初に調整するとすぐに実行されない可能性があります。最初に実行し、同期制御を行う必要があります。
2. このメソッドはブラウザ インターフェイスのレンダリング スレッドを占有する必要があり、このスレッドと JavaScript エンジンのスレッドは相互に排他的です。
20,000以上のデータがあるので、最初は再生速度を制御していたので、最初は問題なかったのですが、後からこの方法だと大量のデータが滞留してしまい、ブラウザインターフェースのレンダリングスレッドが常に占有されてしまい、そのため、メインページがスタックするまで非常にスタックしてしまいます。メイン ページをクリックすると、ブラウザのイベント トリガー スレッドが実行される必要がありますが、この時点ではインターフェイス レンダリング スレッドが実行されているため、非常にスタックします。
解決策:
this.Dispatcher.BeginInvoke(/Access インターフェース UI)、明らかにこれが原因であるため、代替手段を見つけてください。データキューはSilverlight上に配置されていることが分かりましたが、JavaScriptキューに変更しました。データの再生はシルバー スレッドに依存せず、setimeout (IE6 ではこの方法はメモリ リークを引き起こすため、最初は拒否しました) を使用して定期的にデータを再生します。結果は美しく、ページは非常にスムーズで、非同期の問題はなく、同期して再生されるデータを制御する必要がなく、比較的シンプルです。
理由の分析:
Silerlight で再生すると非常にスタックするのに、Setimeout で再生するとスタックしないのはなぜですか? どちらも継続的に再生されます。Setimeout の再生中にページをクリックすると、ページもイベントに応答できます。この問題を解決するには、イベントから JavaScript エンジンを駆動する必要があります。ページがスタックする理由は上で述べましたが、主に setimeout 再生がスタックしない理由を説明したいと思います。ブラウザーの JavaScript エンジンはイベント駆動型です。これらのタスクは、タスクを追加するための setTimeout の呼び出しなど、ブラウザーによって現在実行されているコード ブロックから発生する可能性があります。または、インターフェイス要素のマウス クリック イベント、スケジュールされたトリガー時刻の到着通知、非同期リクエスト ステータスの変更通知など、ブラウザー カーネルの他のスレッドから取得することもできます。コードの観点から見ると、タスク エンティティはさまざまなコールバック関数であり、JavaScriptエンジンは常にタスクキューを待ちます。タスクの到着はシングルスレッドの関係のため、これらのタスクはキューに入れられ、エンジンによって次々に処理される必要があります。したがって、データを再生すると、操作インターフェイスがタスク キューに追加されて実行され、当然、ユーザーはページ全体がスタックしなくなったと感じるでしょう。