C# 我应该升级到能够使用SqlDataReader的新异步方法吗?

C# 我应该升级到能够使用SqlDataReader的新异步方法吗?,c#,.net,asynchronous,.net-4.0,.net-4.5,C#,.net,Asynchronous,.net 4.0,.net 4.5,我正在从事一个在.NET4.0上运行的大型项目。这个框架使用ADO.NET进行数据库调用,我们目前正在添加异步API方法。SqlCommand类具有方法SqlCommand.BeginExecuteReader()和SqlCommand.EndExecuteReader(),但是SqlDataReader没有异步实现。 当SqlCommand.ExecuteReader()完成时,我想使用SqlDataReader迭代结果。Microsoft在.NET4.5中为SqlDataReader引入了异

我正在从事一个在.NET4.0上运行的大型项目。这个框架使用ADO.NET进行数据库调用,我们目前正在添加异步API方法。
SqlCommand
类具有方法
SqlCommand.BeginExecuteReader()
SqlCommand.EndExecuteReader()
,但是
SqlDataReader
没有异步实现。
SqlCommand.ExecuteReader()
完成时,我想使用
SqlDataReader
迭代结果。Microsoft在.NET4.5中为
SqlDataReader
引入了异步方法,因此我不能在4.0中使用这些方法

问题:我们是否应该升级到能够使用
SqlDataReader
的异步()方法? 如果我们这样做了,为什么

我在网上搜索了很多答案,但我似乎只找到了这方面的实现。它没有告诉我这些新实现带来了什么好处

.NET4.0的实现 这里我们使用了
SqlCommand
的异步方法,但不能使用
SqlDataReader
的新异步方法,如
SqlDataReader.ReadAsync()

private Task ExecuteReaderAsync(IDbCommand dbCommand)
{
var sqlCommand=CheckIfSqlCommand(dbCommand);
PrepareExecuteReader(dbCommand);
返回任务
.工厂
.FromAsync(sqlCommand.BeginExecuteReader,sqlCommand.EndExecuteReader,null);
}
私有void ReadAll(任务readerTask)
{
var reader=readerTask.Result;
while(reader.Read())//这应该是异步的吗?
{
//做点什么
}
}
公共任务Foo(IDbCommand dbCommand){
返回ExecuteReaderAsync(dbCommand)
.ContinueWith(readerTask=>ReadAll(readerTask));
}
.NET4.5的实现 在.NET 4.5中,我们可以使用async/await关键字,并且可以为
SqlDataReader
使用新的异步方法,如
SqlDataReader.ReadAsync()

private async Task ExecuteReaderAsync(SqlCommand-dbCommand)
{
PrepareExecuteReader(dbCommand);
返回wait-dbCommand.ExecuteReaderAsync();
}
专用异步任务ReadAll(SqlDataReader)
{
while(wait reader.ReadAsync())//这应该是异步的吗?
{
//做点什么
}
}
公共异步任务Foo(SqlCommand-dbCommand)
{
var reader=await ExecuteReaderAsync(dbCommand);
等待ReadAll(阅读器);
返回读取器;
}

理论上的好处是,应用程序将使用更少的线程,因此在线程开销上消耗更少的内存和CPU资源。这反过来又为您的应用程序或其他系统活动留下了更多的可用资源,从而提高了应用程序的性能和可伸缩性

对于同时接收大量请求的应用程序,其好处可能是巨大的。但是,您只能通过测试特定的应用程序来发现实际的差异。 这是一篇深入细节的好文章

我的观点是,如果您没有发现异步DataReader代码更难理解、阅读和调试,那么继续使用它。它将与您处理命令代码的方式保持一致,异步通常被认为是现代最佳实践。你会失去什么


<>我想提一下,您应该考虑使用更高级的API,即ORM。我认为实体框架和nHibernate是目前.NET最流行的。EF6具有内置的异步支持,对于一个典型的异步查询,您可以简单地使用类似ToListAsync()的东西。先看看吧

谢谢你的回答。实际上,我正在尝试为NHibernate添加一个异步API方法(
ICriteria.ListAsync()
)。概念证明:。NHibernate运行的是ons.NET4.0,所以我不能使用听起来雄心勃勃的
SqlReader.ReadAsync()
@annemartijn,但我祝你好运。在任何情况下,我希望您在查看nHibernate代码时能学到很多东西。也许有一天我也会花时间做同样的事。谢谢@ShawnMartin,我知道我需要一些运气。通过查看NHibernate的代码和实体框架,我已经学到了很多东西。我将在接下来的三个月(大约)内对此进行研究,所以我可能会完成一些事情。