2011-08-16 18 views
4

私はこの質問が以前ここで聞かれたことを知っていますが、私は私を助けなかったいくつかの答えを読んできました。WPF、MVVM、および非同期の仕事

データベースからの選択に関連する情報を取得する必要があるComboBoxがあります(スクロール時に1000回の呼び出しを停止するために、フォーカスが失われている可能性があります)。この情報は表示用であり、クリティカルではないため、バックグラウンドのスレッド/タスクを得ることは完璧な解決策のように聞こえます。それはいくつかの非常に大きなテーブルからカウントを取得しているので、数秒かかる。この情報は表示/参照のみのため、ユーザーは他のタスクに自由に移動する必要があります。

This questionバックグラウンドワーカーを使用することを推奨しますが、この解決策には2つの問題があります。 1)作業者が既に実行している間に選択を変更すると、問題が発生します。 2度目の起動はできません。つまり、新しい選択に対して有効な情報が表示されなくなった場合や、キャンセルする場合(常に機能するとは限りません)などです。 2)私が説明できない何らかの理由で、バックグラウンドワーカーのデータベースに実際にアクセスするメソッドは、モデルにあるメソッドがViewModelの場合よりも遅くなります。私は本当に理由を知らない。

This questionにはいくつかの票がありますが、OPの質問は非常に貧弱であり、選択された回答で「うまく動作するはずです」と表示されます。

This question's methodは有望に見えますが、リンクされた動画は1時間(全部を見ました)、ディスパッチャーに触れずに10〜15秒間だけ説明します。誰かがこの方法をより深くカバーする記事へのリンクを持っているなら、それは良いでしょう。

スレッドプーリング、suggested hereは、ルックアップのために複数の要求がちょうどキューに入れられるようではなく、既に実行中のエラーの原因で、おそらく行くには最高の方法であるように見えるよう。ただし、MSDNの記事にリンクする代わりに、スレッドプールを使用する方法の説明はありません。誰かがこの方法をより深くカバーする記事へのリンクを持っているなら、より良い解決策のように思えるので理想的です(もちろん間違いかもしれません)。

私は実際にこれに関する研究を試みましたが、これらの答えのほとんどは、どのような方法を使用するのかを教えてくれるだけで、使用方法は教えてくれません。私は本当に「ハウツー」を探しています。

+0

正確に非同期的に何をしたいですか? 1)コンボボックスの項目をロードして入力しますか? 2)ユーザーがアイテムを選択したときに何か他の操作を行いますか?あなたは、あなたの実際の問題を明確かつ精緻にするために、質問から他のものをすべて削除する必要があります。 –

+0

私はそれがかなり明確だと思った。私は、コンボボックスを作成する必要はありません、私は行われた選択に関連するデータベースから情報を取得し、UIでこの情報を表示する必要があります。私の問題は、いくつかの解決策が説明なしにstackoverflowの答えとして提唱されているということです。その部分を取り除くと、私はそれらの非常に答え、または同様に薄い回答のいずれかへのリンクを得ることになると思います。 – Tyrsius

答えて

6

OK。あなたの質問:

  1. あなたは
  2. あなたは 現在選択されている項目からいくつかの結果を返す 高価操作を持っているアイテムのリストで選択制御を持っている(この操作だけではなく、高価であることに注意してくださいあなたが同時に多くのものを持っていないことを心配するために、戻りに時間がかかります) - それで、あなたはそれを並行して行う必要があります。
  3. 返された結果は表示されません。非同期に
  4. 現在選択した項目の変更は、あなたは、もはや以前の結果を望んでいない - と、前の要求が最新で、できるだけ早く彼らは

高価をしているので、あなたが何をすべきキャンセルする必要があります。NETテクノロジー:

  1. 使用反応拡張受信(Rx)、それだけで火災ように、ユーザが言う、のために現在の選択を保持したときにスロットルを設定し、少なくとも500ミリ秒(あなたは多くの多くのtaksを起動する必要はありませんユーザーは、下矢印キーを押し続けると)
  2. スロットル火災は、タスク(長時間実行スレッドプールを飢え回避するため)に操作を待つ非同期方法(非同期CTP)を呼び出した場合、およびまたキャンセルトークンを入れてください。後で比較のために現在の選択内容を保存する
  3. 操作が返ってきたら、その結果をデータコンテキスト(ディスプレイコントロールにバインドする必要があります)に設定します。非同期メソッドは常にUIスレッドで続行されるため、スレッドのアクセスを心配する
  4. スロットルが発生し、未処理のタスク/キャンセルトークンがある場合は、まずキャンセルトークンを使用してタスクをキャンセルし、#2で新しいタスクを開始します。タスクがキャンセルされているため待ち状態になりますが、タスクがキャンセルされても問題はありません。
  5. Async CTPは常にUIスレッド上で続行されるため、ここで並行処理の問題は発生しません。あなたのすべての操作に関する限り、それらはすべてシングルスレッドであり、お互いを踏み外さないでしょう。

私は、Rxで非同期CTPを使用すると、約10行のコードだと思います。

注:操作がNOT EXPENSIVEの場合、キャンセルトークンを使用する必要はありません。タスクを完了して実行するだけですが、結果は無視してください。ただし、クライアントマシンでは高価ではありませんが、サーバーでは高価ですが、データベースクエリを早期にキャンセルすることをお勧めします。

+0

これは素晴らしいですが、私はそれをテストするまで答えとしてマークすることはできませんし、RXやAsync CTPの使い方がわからないので、チュートリアルのためにオンラインで狩猟をする必要があります。おそらく物事をスピードアップさせるリンクがある場合。しかし、非常に良い答えをありがとう! – Tyrsius

3

あなたはバインディング非同期を使用するように試みることができる:

<ComboBox Name="theCombo" ... /> 
<TextBlock Text="{Binding Path=SomeSlowProperty, ElementName=theCombo, IsAsync=True}" /> 
関連する問題