我正在使用 .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>`)
}
}
我收到警告
This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
我正在考虑按照警告中的建议将 command.ExecuteReader()
语句转换为 await Task.Run(() => command.ExecuteReader())
.但我不确定这是正确的方法,我相信 Task.Run(...)
用于执行基于 CPU 的工作。这主要是 IO 工作。
所以我的问题是
Task.Run(...)
是正确的方法吗?- 如果没有,是否有其他解决方案?
- 或者我是否应该暂时忽略警告,等到
ExecuteReaderAsync
添加到IDbCommand
接口(interface)? (有这方面的计划吗?)
最佳答案
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
并添加 await 就可以了,例如
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 和其他所有内容。
关于c# - IDbCommand 缺少 ExecuteReaderAsync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45837012/