问题描述
使用ASP.NET 4.5我试图用新的异步播放/等待玩具。我有一个的IDataReader,实现类,包装了一个供应商特定的读者(如SqlDataReader的)。我有一个同步运行,像这样一个简单的ExecuteSQL()方法:
With ASP.NET 4.5 I'm trying to play with the new async/await toys. I have a IDataReader-implementing class that wraps a vendor-specific reader (like SqlDatareader). I have a simple ExecuteSql() method that operates synchronously like so:
public IDataReader ReaderForSql(string sql)
{
var cmd = NewCommand(sql, CommandType.Text);
return DBReader.ReaderFactory(cmd.ExecuteReader());
}
我要的就是这样的一个异步版本。这是我第一次尝试:
What I want is an Async version of this. Here's my first try:
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我得到了worreid关于他们给了有关警告:
This works great in my limited testing so far. But after watching this Cloud9 video a few times: http://channel9.msdn.com/Events/aspConf/aspConf/Async-in-ASP-NET I got worreid about warnings they gave regarding:
- ContinueWith摄入额外的线程池资源 - !Readerfactory很轻
- Task.Result阻塞
和因为我传递一个ContinuationToken到ExecuteReaderAsync()似乎取消仅仅是另一个原因ExecuteReaderAsync()可能失败(它的SQL毕竟!)
and since I am passing a ContinuationToken to ExecuteReaderAsync() it seems cancellation is just yet another reason ExecuteReaderAsync() could fail (it's SQL after all!)
会有什么任务的状态,当我尝试ContinueWith呢?将t.Result块?扔?做错事?
What will be the state of the task when I try to ContinueWith it? Will t.Result block? throw? do the wrong thing?
推荐答案
ContinueWith
将使用当前的任务调度程序(线程池线程)在默认情况下,但你可以改变通过传递 TaskContinuationOptions.ExecuteSynchronously
和明确的的TaskScheduler
。
ContinueWith
will use the current task scheduler (a thread pool thread) by default, but you can change that by passing TaskContinuationOptions.ExecuteSynchronously
and an explicit TaskScheduler
.
这是说,我会做这个作为第一次尝试:
That said, I would make this as a first effort:
public async Task<IDataReader> ReaderForSqlAsync(string sql, CancellationToken ct)
{
var cmd = NewCommand(sql, CommandType.Text);
var readerResult = await cmd.ExecuteReaderAsync(ct).ConfigureAwait(false);
return DBReader.ReaderFactory(readerResult);
}
异步
和等待
处理所有的 ContinueWith
美食和边缘条件为您提供了一致的方式。它可能会为这个code复杂化要快如果性能测试表明这是一个严重的问题。
async
and await
handle all the ContinueWith
delicacies and edge conditions in a consistent manner for you. It may be possible to complicate this code to be faster if performance testing indicates it's a serious problem.
这篇关于Task.ContinueWith混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!