0

申請に取り組んでいwpfます。このアプリケーションは、レポートを表示するために使用されます。このために、2 つのタブがあります。1 つは列を選択するためのタブで、もう 1 つはlistview他のフィルターです。2 番目のタブには、sqlテーブルからの結果が表示されます。ここで動的クエリの場合、サーバー側でクエリを作成し、これをストアドプロシージャにパラメーターとして渡し、そこでexecuteメソッドを使用して実行しています。

問題 :

合計170列からいくつかの列を選択するとうまくいきますが、リストビューですべての列を選択して他のタブに移動しようとすると、同じタブに残り、例外がスローされます:

The CLR has been unable to transition from COM context 0xc40048 to COM context
0xc401b8 for 60 seconds. 

これには数千行のフェッチがあります。

質問 :

1.)クエリの実行を高速化する方法。

2.) データのファッティングのためにテーブルをより高速にするための手順。

4

4 に答える 4

3

COM コンテキスト遷移の試行中にデッドロックが検出されると、contextSwitchDeadlock マネージ デバッグ アシスタント (MDA) がアクティブになります。

症状

最も一般的な症状は、マネージ コードからのアンマネージ COM コンポーネントの呼び出しが返されないことです。もう 1 つの症状は、時間の経過とともにメモリ使用量が増加することです。

原因

最も可能性の高い原因は、シングル スレッド アパートメント (STA) スレッドがメッセージをポンピングしていないことです。STA スレッドが、メッセージをポンピングせずに待機しているか、時間のかかる操作を実行しており、メッセージ キューのポンピングを許可していません。

時間の経過とともにメモリ使用量が増加するのは、ファイナライザー スレッドがアンマネージ COM コンポーネントで Release を呼び出そうとし、そのコンポーネントが返されないことが原因です。これにより、ファイナライザーが他のオブジェクトを再利用できなくなります。

デフォルトでは、Visual Basic コンソール アプリケーションのメイン スレッドのスレッド モデルは STA です。この MDA は、STA スレッドが共通言語ランタイムまたはサードパーティ コントロールを介して直接的または間接的に COM 相互運用性を使用する場合にアクティブ化されます。Visual Basic コンソール アプリケーションでこの MDA をアクティブにしないようにするには、MTAThreadAttribute 属性をメイン メソッドに適用するか、メッセージをポンプするようにアプリケーションを変更します。

次の条件がすべて満たされると、この MDA が誤ってアクティブ化される可能性があります。

· アプリケーションは、STA スレッドから直接またはライブラリを介して間接的に COM コンポーネントを作成します。

· アプリケーションがデバッガで停止され、ユーザーがアプリケーションを続行するか、ステップ操作を実行しました。

· アンマネージ デバッグが有効になっていません。

MDA が誤ってアクティブ化されているかどうかを判断するには、すべてのブレークポイントを無効にし、アプリケーションを再起動して、停止せずに実行できるようにします。MDA がアクティブ化されていない場合は、最初のアクティブ化が誤っていた可能性があります。この場合、MDA を無効にして、デバッグ セッションへの干渉を回避します。

解像度

STA メッセージ ポンピングに関する COM ルールに従います。

これらのエラー ポップアップが表示されないようにするには、Visual Studio ウィンドウの [デバッグ] メニューから [例外] を選択し、[例外] ダイアログ ボックスで [マネージド デバッグ アシスタント] 例外ノードを選択します。次に、ContextSwitchDeadlock を選択し、Thrown 列から選択を削除します。

ここに画像の説明を入力

実行を高速化する方法:

それを行うには多くの方法があります

テーブルに不足しているインデックスを作成します。

このテーブルにインデックス付きビューを作成します。

データ範囲に基づいてテーブルを分割することもできます。

このテーブルを別のディスクに配置して、データの読み取り/書き込みが高速になるようにします。

于 2012-05-09T12:17:04.433 に答える
1

いくつかのアイデア:

  • BackgroundWorkerクラスを使用して、WPFで作業しDispatcherます。
  • 結果をページングする-無限のスクロール効果を作成することもできます
  • DataSetの代わりにDataReaderを使用する
  • タブ2のコントロールのレンダリングを非表示/無効にし、データをバインドして、コントロールを再度有効にします。SuspendLayoutWinFormsでは、 /を使用しますResumeLayout
  • UIを変更する-人間が170列を処理する方法を想像することはできません...おそらく、提供できるデータのより良い(多くの場合、より単純な)表示があります

最終的には、コールスタックのどこにパフォーマンスの問題があるかを判断する必要があります。Visual Studioデバッガーはこれに役立つはずですが、他のツールを使用する必要がある場合があります。SQL Profilerを使用して、ストアドプロシージャ/SQLServerの動作を分析します。ネットワーク接続については、WireSharkのようなものを試してください。

編集: Dispatch/BackgroundWorkerリンクを追加---タイムアウトが発生している場所を知る必要があります。

于 2012-05-09T12:32:11.240 に答える
0

個人的には、アプリケーション自体ではなく SQL レベルで結果をフィルタリングすることをお勧めしますが、ここにはアプリケーション側のパフォーマンスも向上させるいくつかの回答があり、それらに従う必要があります。

SQL ページングを使用するサンプル コードについては、「T-SQL: Paging with ROW_NUMBER() 」を参照してください。

于 2012-05-09T12:34:49.330 に答える
0

データベース呼び出しをより効率的にしたい場合は、Enterprise Library を試してみることをお勧めします。現在のバージョンは 5.0 です。私たちのアプリケーションでうまくいきました。

http://msdn.microsoft.com/en-us/library/ff648951.aspx

于 2012-05-09T12:19:56.893 に答える