BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース 検討しよう、ADO.NET 4.5の非同期とストリーミング

検討しよう、ADO.NET 4.5の非同期とストリーミング

原文(投稿日:2012/05/29)へのリンク

まだ一連の DataReaderクラスで直接開発している.NET開発者のために、.NET 4.5は、いくつかの新しい非同期のストリーミングサポートを提供する。

SqlDataReader によって、開発者は便利さは犠牲になるがよりよいパフォーマンスを手に入れることができる。例えば、このクラスは通常、一度に全行読み込むが、サーバーからどれだけのパケットを待つ必要があるかは考慮しない。そしてもし複数の大きなオブジェクトコラムがある場合、それらは一気にメモリーに保存される。もしシーケンシャル・アクセスに変えて、もはや全行をバッファする必要がない場合、コラムを順に読まなければならない。

.NET 4.5によって、シーケンシャル・アクセスを使っている開発者は、NextResultAsync, ReadAsync, IsDBNullAsync, 、GetFieldValueAsync<T>を選びながら使えば、更にパフォーマンスの微調整ができる。 ADO.NET 4.5の非同期メソッド は、自動的なパフォーマンス加速器ではなく、おそらくシングルスレッドに対してはスピードアップにならないことをはっきり理解すべきである。それらは、たくさんの同時リクエストを処理する時に役立つ。なぜならそれらは、スレッドに対するブロッキングを減らすからである。まずい点は、Taskオブジェクトを作らなければならないことである。これは、ガーベッジコレクションの妨げになるからである。一般的なアドバイスは以下のようになる。

  1. パケット処理を非同期にやれる時は、常に NextResultAsyncを使う。
  2. いずれのモードでも ReadAsyncの方を使う。またしても、パケット処理のほとんどは、非同期にできる。
  3. 非シーケンシャルモードでは、 IsDBNullAsync と GetFieldValueAsyncは、使わない。このモードでは、コラムはすでにバッファされており、Taskオブジェクトを無駄に生成することになる。

シーケンシャルモードに対しては、 GetFieldValueAsyncを使う決断は、もう少し複雑である。 Daniel Paoliello氏の説明によれば、

しかし、もし非シーケンシャルアクセスモードでReadを呼んだり、もしシーケンシャルアクセスモードを使っているなら、決定はずっと難しくなります。お望みのコラムにどれだけのデータを読み込む必要があるのか、そのコラムはどれだけのデータを持てるのかを考える必要があるからです。もし前のコラムを読み、ターゲットコラムが小さい( Boolean, DateTime あるいは数値型のように)なら、同期メソッドを使うことを考えるかもしれません。代わりに、ターゲットコラムが大きい(varbinary(8000)のように)か終わったばかりの大きなコラムを読む必要がある場合、非同期メソッドを使うほうがずっといいです。最後にもしターゲットコラムが巨大な場合( varbinary(MAX), varchar(MAX), nvarchar(MAX) あるいは XMLのように)は、新しいGetStream, GetTextReader あるいは GetXmlReader メソッドを考えるべきです。

データベースに保存されている大きなファイルを扱うときは、ストリームベースのメソッドを使うほうが有利だ。例えば、 WCF やASP.NETレスポンスにストリームで流せる。一度に全ファイルをメモリーに取り込む必要はない。このことは特に.NET開発者には重要である。なぜなら大きなオブジェクトヒープは、非常にフラグメンテーションの影響を受けやすいからである。

この記事に星をつける

おすすめ度
スタイル

BT