IDbCommand缺少ExecuteReaderAsync

时间:2017-08-23 10:19:28

标签: c# asynchronous async-await .net-core-2.0

我正在使用.NET Core 2.0。我有以下函数调用IDbCommand.ExecuteReader

public async Task<IEnumerable<Widget>> ReadAllAsync(
    System.Data.IDbConnection databaseConnection,
    System.Data.IDbTransaction databaseTransaction)
{
    var commandText = "SELECT WidgetId, Name FROM Widget";

    // _databaseCommandFactory.Create returns an IDbCommand
    var command = this._databaseCommandFactory.Create(databaseConnection, databaseTransaction, commandText);

    using (var dataReader = command.ExecuteReader())
    {
        // iterate through the data reader converting a collection of Widgets (`IEnumerable<Widget>`)
    }
}

我收到警告

  

这种异步方法缺少'await'运算符并将同步运行。考虑使用'await'运算符等待非阻塞API调用,或'await Task.Run(...)'在后台线程上执行CPU绑定工作。

我正在考虑按警告中的建议将command.ExecuteReader()语句转换为await Task.Run(() => command.ExecuteReader())。但我不确定这是正确的方法,我相信Task.Run(...)是基于CPU的工作。这主要是IO工作。

所以我的问题是

  1. Task.Run(...)是正确的做法吗?
  2. 如果没有,还有另一种解决方案吗?
  3. 或者我现在应该忽略警告并等待ExecuteReaderAsync添加到IDbCommand界面? (有计划吗?)

1 个答案:

答案 0 :(得分:6)

await关键字允许该方法异步运行。 async关键字允许在方法中使用await关键字,并协助管理退货。

在调用await之前,该方法将同步运行。

所以这一切都是同步运行的。在完成之前,它不会返回任何内容或移动方法。

public async Task<IEnumerable<Widget>> ReadAllAsync(
    System.Data.IDbConnection databaseConnection,
    System.Data.IDbTransaction databaseTransaction)
{
    var commandText = "SELECT WidgetId, Name FROM Widget";

    // _databaseCommandFactory.Create returns an IDbCommand
    var command = this._databaseCommandFactory.Create(databaseConnection, databaseTransaction, commandText);

    using (var dataReader = command.ExecuteReader())
    {
        // iterate through the data reader converting a collection of Widgets (`IEnumerable<Widget>`)
    }
}

通过转换为DbCommand,大多数IDbCommand派生的实现已经执行,然后转换为DbCommand并添加等待将会起作用。

var dbCommand = (DbCommand) command;
using (var dataReader = await dbCommand.ExecuteReaderAsync())
{
    while (await dataReader.ReadAsync()) 
    {
        // iterate through the data reader converting a collection of Widgets (`IEnumerable<Widget>`)
    }
}

或创建单独的任务

public async Task MyAsyncMethod()
{
  // Do your stuff that takes a long time
}

public async Task CallMyAsyncMethod()
{
  // We can await Tasks, regardless of where they come from.
  await MyAsyncMethod();

}

这样 - 程序将在等待从此方法返回时继续,而不是锁定UI和其他所有内容。