1

この質問が少し一般的に聞こえる場合はお詫び申し上げます。この問題を解決する方法についての一般的なアドバイスを探しています:)

現在、カスタム FileService でファイルのリストを取得する次の非同期メソッドがあります。これは、ViewModel のコンストラクターで発生しています。

private async void Construct()
{
   Files = new ObservableCollection<FileViewModel>();
   IList _files = await _fileRepository.GetFiles();
   foreach (File file in _files)
   {
      Files.Add(new FileViewModel(file));
   }
}

おそらく解決できるように、非同期メソッドはファイルのリストを 1 つのステップで取得し、それらをリスト (UI のバインディング ソース) に追加して別のステップに追加します。

ユーザーには、非同期プロセスが完了するまで何も表示されず、しばらくするとすべての結果が一度に表示されます。

私の頭の中で、これは非同期のポイントを無効にします。なぜなら、私が本当に欲しいのは、結果が取得されるときに追加される結果だからです。

別のステップを追加するために、各ファイルの最初の文字を取得してカテゴリにグループ化する linq クエリもあります。これは foreach ループの後に実行されます。このステップも追加するにはどうすればよいですか?

あなたが与えることができる任意のアドバイスをありがとうございました!

4

2 に答える 2

2

これを行うには、リポジトリを基本的なレベルで変更する必要があります。アイテムが取得されたときにイベントを発生させるオブジェクトを返し、イベント ハンドラーで、コントロールがバインドされているINotifyCollectionChangedインターフェイスの実装にオブジェクトを追加できます。

また、 Reactive Extensionsを調べて、サブスクライブすると項目をデータ ソースに追加するIObservable<T>インターフェイスの実装を公開することもできます (ここでも を実装していますINotifyCollectionChanged)。

どちらのアプローチを取るにしても、UI コンポーネントは作成されたスレッドでのみ更新されるという事実を考慮する必要があります。つまり、UI スレッドへの呼び出しをマーシャリングする必要があります。

これを行う最も簡単な方法は、非同期呼び出しを行う前に静的プロパティSynchronizationContextを使用してキャプチャし、呼び出しでメソッドを呼び出して項目を実装に追加することです。CurrentPostINotifyCollectionChanged

async/awaitは、この状況ではあまり役に立ちません。操作が完了したときの通知には適していませんが、非同期操作が完了したときに継続を織り込むには適していません。

ただし、これらのアプローチを再検討することをお勧めします。ほとんどの LINQ プロバイダーでIQueryable<T>は、 から派生した が返されIEnumerable<T>ます。が繰り返されている間にブロックが発生する可能性は確かにありますがIEnumerable<T>、ほとんどのプロバイダーは結果をかなり素早く連続してストリーミングします。

LINQ プロバイダーそれらを提供するのが遅すぎる場合 (各反復間の大きなギャップ)、リアクティブ フレームワークのToObservable拡張メソッドを使用して、上記のパターンのいずれかを有効にして、リストに配置するアイテムをすぐに提供できます。それらを得る。

于 2012-10-03T00:24:25.527 に答える
1

これを行うには、ファイル リポジトリを変更する必要があります。

TPL Dataflow を使用することをお勧めします。ファイル リポジトリで、データBufferBlock<File>がいっぱいになることを公開し、コードでそれを使用するようにします。

于 2012-10-02T21:00:20.877 に答える