ASP.NET 4.5 を使用して、新しい async/await おもちゃで遊んでいます。ベンダー固有のリーダー (SqlDatareader など) をラップする IDataReader 実装クラスがあります。次のように同期的に動作する単純な ExecuteSql() メソッドがあります。
public IDataReader ReaderForSql(string sql)
{
var cmd = NewCommand(sql, CommandType.Text);
return DBReader.ReaderFactory(cmd.ExecuteReader());
}
私が欲しいのは、これの非同期バージョンです。これが私の最初の試みです:
public Task<IDataReader> ReaderForSqlAsync(string sql, CancellationToken ct)
{
var cmd = NewCommand(sql, CommandType.Text);
return cmd.ExecuteReaderAsync(ct)
.ContinueWith(t => DBReader.ReaderFactory(t.Result));
}
そして私はそれを使用します:
using (var r = await connection.ReaderForSqlAsync("SELECT ...", cancellationToken))
{
...
}
これは、これまでの限られたテストではうまく機能します。しかし、この Cloud9 ビデオを数回見た後: http://channel9.msdn.com/Events/aspConf/aspConf/Async-in-ASP-NETに関する警告について心配になりました。
- 追加のスレッドプール リソースを消費して続行 - Readerfactory は非常に軽量です。
- Task.Result ブロッキング
ContinuationToken を ExecuteReaderAsync() に渡しているので、キャンセルは ExecuteReaderAsync() が失敗する可能性があるもう 1 つの理由のようです (結局のところ SQL です!)
ContinueWith を実行しようとすると、タスクの状態はどうなりますか? t.Result はブロックしますか? 投げる?間違ったことをしますか?