2016-11-12 30 views
1

私の環境はASP.NETコアとEFコアです。要求の間、エンティティのコレクションを非同期に「ページング」する必要があります。ASP.NET環境でコレクションを非同期で列挙するにはどうすればよいですか?

public class PagedList<T> : IEnumerable<T> { /* ... */ } 

そして非同期列挙のために、この拡張メソッド:

だから私は、このコレクションクラスを作成

public static async Task<PagedList<T>> ToPagedListAsync<T>(this IQueryable<T> items, int pageSize, int pageNumber) { 
    return await Task.Run(() => new PagedList<T>(items, pageSize, pageNumber)); 
} 

をそして今、私はこれを行うことができます:

var stuff = await repository.CreateQueryableForLoadingStuff().ToPagedListAsync(10, 1); 

を私は見案内のためのsource for EF's ToListAsync() - 私がやったように同期操作をラップするだけではなく、 rは非同期的に新しいコレクションに直接列挙されます。 メソッドは、Task.Run()を使用して新しいスレッドを開始し、ASP.NETリクエスト内で操作しているため、間違ったアプローチである可能性があるため、実際には非同期ではないことを説明しているI also saw thisです。

自分の環境(ASP.NETコアとEFコア)が正しいですか、そのリンクの方法を使用する必要がありますか?また、.ConfigureAwait(false)を使用する必要がありますか?

+4

これはASP.NETの悪い手法です。あなたがしているのはスレッドを作ることだけです。すべてのASP.NET要求は既にスレッドプールスレッドで発生しています。なぜ追加のスレッドを作成するのですか?また、あなたの例から見るのは難しいですが、C#でページングを行う予定があるようです。なぜデータベースはそれをしないのですか?それははるかに効率的です。 10行しか必要ない場合は、10000をすべて返さずに最初の10行を選択し、必要な結果を得るために 'Skip'と' Take'を使います。 – dman2306

+0

@ dman2306 'PagedList'クラスはEFの' Skip'と 'Take'を使ってデータベースのページングを行います。これは私が心配している非同期列挙です。だから、それが悪いASP.NETの場合、私は代わりに何をすべきですか? – grokky

+3

EFのようなことをしたいと思うでしょう。目標はI/O非同期化です。つまり、ソケットがデータを読み取るのを待っている間に、OSがIOを待つ間、スレッドが使用されていない間にASP.NET要求スレッドをスレッドプールに戻す必要があります。 – dman2306

答えて

0

私はあなたの非同期コンポーネントを間違って配置していると思います。代わりにI/O部(EF /リポジトリ)、いないメモリ内の一部(PagedList)に非同期にしたいので、これはどう:

public static PagedList<T> ToPagedList<T>(this IQueryable<T> items, int pageSize, int pageNumber) { 
    return new PagedList<T>(items, pageSize, pageNumber); 
} 

次に、あなたがこれを行うことができます...

var stuff = (await repository.CreateQueryableForLoadingStuffAsync()).ToPagedList(10, 1); 

...最初に意図したものから括弧でくくっているだけです。

編集:コメントと同じように、これはSQLクエリを制約するためにクエリ可能を効果的に使用することはできず、メモリ内でページングされます。クエリ可能な作業を効果的に行うための代替方法として、PagedList and Async

+0

それはちょうどタイプミスだと思う。しかし、実際問題ではありません。構文上の問題ではありません。新しいスレッドに列挙をオフロードするか、非同期的に新しいコレクションに列挙するかは、ASP.NET環境では優れています。 – grokky

+0

また、このアプローチはテーブル全体をプルダウンし、メモリ内でページングを実行します。私のPagedListクラスは上記のように 'Skip'と' Take'を発行するのに対し、非同期操作の一部である必要があります。 – grokky

+0

Trueですが、PagedListのコンストラクタは、タスクではなくIQueryableを使用します。別のオプションへのリンクを含む編集を追加しました。 – sellotape

関連する問題