本文介绍了Task.ContinueWith混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用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混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-24 16:10