这是向 IDbCommand 接口(interface)添加异步功能的合理方法吗?
public async static Task<IDataReader> ExecuteReaderAsync(this IDbCommand self) {
DbCommand dbCommand = self as DbCommand;
if (dbCommand != null) {
return await dbCommand.ExecuteReaderAsync().ContinueWith(task => (IDataReader)task.Result);
} else {
return await Task.Run(() => self.ExecuteReader());
}
}
具体来说,我不完全确定使用“ContinueWith”来伪造“任务”的协方差会产生什么影响。
此外,在不太可能的情况下,传入的“self”实例不继承自 DbCommand,在执行“self.ExecuteReader()”期间是否会消耗并阻塞线程池线程?
这是a link到我对异步支持的 IDb 扩展的完整实现。
谢谢
最佳答案
只是因为它更干净,我会利用您使用的事实 async
和 await
取消 ContinueWith()
中的类型转换. await
评估为 TResult
类型的对象在 Task<TResult>
上使用时.我打算建议语法 return (IDataReader)await dbCommand.ExecuteReaderAsync();
, 但后来我想起编译器已经知道 DbDataReader
是IDataReader
.在 VS 2013 和 VS 2015 预览版中测试(不确定您的目标是什么,但我假设所有支持 await
的 C# 编译器都应该适用于此):
public async static Task<IDataReader> ExecuteReaderAsync(this IDbCommand self) {
DbCommand dbCommand = self as DbCommand;
if (dbCommand != null) {
return await dbCommand.ExecuteReaderAsync();
} else {
return await Task.Run(() => self.ExecuteReader());
}
}
现在您正在使用 await
充分发挥其潜力并节省几个字节的代码 ;-)。
这个实现最大的问题当然是 self as DbCommand
中的运行时类型测试。 .在我看来, DbCommand
should be used instead of IDbCommand
.这将使您删除运行时转换。但是,如果从 IDbCommand
切换所有内容没有问题,您可能不会编写此库。至 DbCommand
并且运行时类型检查的性能可能已经足够了。
Visual Studio 2017 语法
对于较新版本的 C#,您可以使用 is
关键字而不是 as
编写更简洁的代码:
public async static Task<IDataReader> ExecuteReaderAsync(this IDbCommand self) {
if (self is DbCommand dbCommand) {
return await dbCommand.ExecuteReaderAsync();
} else {
return await Task.Run(() => self.ExecuteReader());
}
}
关于c# - IDbCommand 接口(interface)中缺少异步功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26150108/