System.Data.Common.DbDataReader.ReadAsync 中的异步是什么?
What is async in System.Data.Common.DbDataReader.ReadAsync?
我正在 MS reference 查看 DbDataReader(也是 DbCommand)的代码,但无法弄清楚 ReadAsync() 方法中的异步是什么。
virtual public Task<bool> ReadAsync(CancellationToken cancellationToken) {
if (cancellationToken.IsCancellationRequested) {
return ADP.CreatedTaskWithCancellation<bool>();
}
else {
try {
return Read() ? ADP.TrueTask : ADP.FalseTask;
}
catch (Exception e) {
return ADP.CreatedTaskWithException<bool>(e);
}
}
}
ReadAsync 方法只是调用 Read 方法,return是一个完整的任务。
这不是和直接调用Read一样阻塞调用线程吗?
我注意到 DbCommand ExecuteReaderAsync 和其他方法中存在相同的模式。他们只是调用同步版本和 return 完成的任务。
我在这里错过了什么?
更新:我没有遗漏任何东西,@PeterBons 解释得很好(也在 the documentation 中)。我还是不喜欢,但这是我的问题。
您正在查看摘要中的虚方法 class。如果您希望(未来的)实现能够完成一些真正的异步工作,您将必须定义一个允许这样做的方法签名。所以它应该 return 一个 Task
或 Task<T>
。请记住,仅使用 Task 不会使任何事情异步,而是使其可等待。
在此示例虚方法中使用 Task<bool>
return 类型是为了方便其他 class 从 DbDataReader 派生的实体在其 ReadAsync 实现中提供真正的异步行为。
例如,真正的异步实现可以做类似
的事情
class TrueAsyncReader : DbDataReader
{
...
public override async Task<bool> ReadAsync(CancellationToken cancellationToken)
{
...
return await ReadFromDbAsync();
}
}
如您所见,您现在可以拥有异步和非异步实现,而无需更改方法签名。
因为您可以轻松地从异步方法调用同步代码,所以这是可行的方法。从同步方法调用异步代码很麻烦。
对于需要 return 任务的非异步实现,您可以 return 类似 Task.FromResult<T>
或 Task.CompletedTask
的东西。这不会阻塞。
另见
总而言之:默认实现不执行任何异步操作,但派生的 classes 可以在不更改方法签名的情况下执行。
我正在 MS reference 查看 DbDataReader(也是 DbCommand)的代码,但无法弄清楚 ReadAsync() 方法中的异步是什么。
virtual public Task<bool> ReadAsync(CancellationToken cancellationToken) {
if (cancellationToken.IsCancellationRequested) {
return ADP.CreatedTaskWithCancellation<bool>();
}
else {
try {
return Read() ? ADP.TrueTask : ADP.FalseTask;
}
catch (Exception e) {
return ADP.CreatedTaskWithException<bool>(e);
}
}
}
ReadAsync 方法只是调用 Read 方法,return是一个完整的任务。 这不是和直接调用Read一样阻塞调用线程吗?
我注意到 DbCommand ExecuteReaderAsync 和其他方法中存在相同的模式。他们只是调用同步版本和 return 完成的任务。
我在这里错过了什么?
更新:我没有遗漏任何东西,@PeterBons 解释得很好(也在 the documentation 中)。我还是不喜欢,但这是我的问题。
您正在查看摘要中的虚方法 class。如果您希望(未来的)实现能够完成一些真正的异步工作,您将必须定义一个允许这样做的方法签名。所以它应该 return 一个 Task
或 Task<T>
。请记住,仅使用 Task 不会使任何事情异步,而是使其可等待。
在此示例虚方法中使用 Task<bool>
return 类型是为了方便其他 class 从 DbDataReader 派生的实体在其 ReadAsync 实现中提供真正的异步行为。
例如,真正的异步实现可以做类似
的事情class TrueAsyncReader : DbDataReader
{
...
public override async Task<bool> ReadAsync(CancellationToken cancellationToken)
{
...
return await ReadFromDbAsync();
}
}
如您所见,您现在可以拥有异步和非异步实现,而无需更改方法签名。
因为您可以轻松地从异步方法调用同步代码,所以这是可行的方法。从同步方法调用异步代码很麻烦。
对于需要 return 任务的非异步实现,您可以 return 类似 Task.FromResult<T>
或 Task.CompletedTask
的东西。这不会阻塞。
另见
总而言之:默认实现不执行任何异步操作,但派生的 classes 可以在不更改方法签名的情况下执行。