首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Task.ContinueWith混淆

Task.ContinueWith混淆
EN

Stack Overflow用户
提问于 2012-11-30 18:58:53
回答 2查看 3K关注 0票数 6

使用ASP.NET 4.5,我正在尝试玩新的异步/等待玩具。我有一个IDataReader实现类,它封装了特定于供应商的读取器(如SqlDatareader)。我有一个简单的ExecuteSql()方法,它同步地操作如下:

代码语言:javascript
复制
public IDataReader ReaderForSql(string sql)
{
    var cmd = NewCommand(sql, CommandType.Text);
    return DBReader.ReaderFactory(cmd.ExecuteReader());
}

我想要的是这个异步版本。我的第一次尝试是:

代码语言:javascript
复制
public Task<IDataReader> ReaderForSqlAsync(string sql, CancellationToken ct)
{
    var cmd = NewCommand(sql, CommandType.Text);
    return cmd.ExecuteReaderAsync(ct)
              .ContinueWith(t => DBReader.ReaderFactory(t.Result));
}

我用它:

代码语言:javascript
复制
using (var r = await connection.ReaderForSqlAsync("SELECT ...", cancellationToken))
{
    ...
}

到目前为止,这在我有限的测试中非常有用。但在看过这段Cloud9视频几遍之后:http://channel9.msdn.com/Events/aspConf/aspConf/Async-in-ASP-NET,我对他们发出的警告感到担忧:

  • ContinueWith消耗额外的线程池资源-- Readerfactory非常轻!
  • Task.Result阻塞

而且,由于我将一个ContinuationToken传递给ExecuteReaderAsync(),取消似乎只是ExecuteReaderAsync()可能失败的另一个原因(毕竟是SQL!)

当我尝试ContinueWith时,任务的状态是什么?t.Result会阻止吗?扔?做错事了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-30 20:06:46

默认情况下,ContinueWith将使用当前任务调度程序(线程池线程),但是您可以通过传递TaskContinuationOptions.ExecuteSynchronously和显式TaskScheduler来更改这一点。

话虽如此,我要把这作为第一次努力:

代码语言:javascript
复制
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);
}

asyncawait以一致的方式处理所有ContinueWith美味和边缘条件。如果性能测试表明这是一个严重的问题,那么可能会使这段代码变得更快一些。

票数 5
EN

Stack Overflow用户

发布于 2012-11-30 19:39:17

如果任务尚未完成,Result将阻塞。但是在延续处理程序中,它已经有了。所以它不会阻塞。你做的是对的。

当您在错误的任务上调用Result (您说这可能发生)时,会重新引发异常。这将导致您的继续与相同的异常发生故障,这将导致从ReaderForSqlAsync返回的最终任务也出现故障。这是一件好事:整个任务链出现故障,所有异常都已被观察到(与被吞食相比)。所以这也是最佳实践。

在计算绑定工作中使用线程总是可以的。因此,您再次使用ContinueWith做了正确的事情。毕竟,你必须在某个地方计算IDataReader。你不能不计算它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13651383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档