这是向IDbCommand接口添加异步功能的合理方法吗?
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());
}
}
具体来说,我并不完全确定使用&#34; ContinueWith&#34;伪造&#34;任务&#34;的协方差。
此外,在不太可能的情况下,来自&#34; self&#34;实例不从DbCommand继承,在执行&#34; self.ExecuteReader()&#34;?
期间是否会消耗和阻塞线程池线程在这里a link完全实现了异步支持的IDb扩展。
谢谢
答案 0 :(得分:3)
如果您使用的是.NET 4.5,则缺少async
和await
。你尝试的方式是正确的,希望你分别处理连接。
public static async Task<IDataReader> ExecuteReaderAsync(this IDbCommand self)
{
var dbCommand = self as DbCommand;
if (dbCommand != null)
{
return await dbCommand.ExecuteReaderAsync();
}
return await Task.Run(() => self.ExecuteReader());
}
答案 1 :(得分:3)
只是因为它更干净,我会利用你使用async
和await
取消ContinueWith()
中的广告投放这一事实。 await
在TResult
上使用时,Task<TResult>
会评估为return (IDataReader)await dbCommand.ExecuteReaderAsync();
类型的对象。我打算建议语法DbDataReader
,但后来我记得编译器已经知道IDataReader
是await
。在VS 2013和VS 2015 Preview中测试过(不确定您的目标是什么,但我认为所有支持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());
}
}
的C#编译器都应该使用此功能):
await
现在,您正在使用self as DbCommand
来发挥更大的潜力并节省几个字节的代码; - )。
此实现的最大问题当然是IDbCommand
中的运行时类型测试。在我看来,DbCommand
should be used instead of IDbCommand
。这将允许您删除运行时强制转换。但是,如果将所有内容从DbCommand
切换到is
并且运行时类型检查可能性能不足,则可能不会编写此库。
使用较新版本的C#,您可以使用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());
}
}
来编写更简洁的代码:
{{1}}