我正在使用.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工作。
所以我的问题是
Task.Run(...)
是正确的做法吗?ExecuteReaderAsync
添加到IDbCommand
界面? (有计划吗?)答案 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和其他所有内容。