- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
有一些文章表明异步数据库调用在 .NET 中不是一个好主意。
在 C# Async CTP 上,有一个名为 ExecuteReaderAsync
的 System.Data.SqlClient.SqlCommand
扩展。我对我现有的代码有如下一些操作:
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString;
using (var conn = new SqlConnection(connectionString)) {
using (var cmd = new SqlCommand()) {
cmd.Connection = conn;
cmd.CommandText = "sp$DetailsTagsGetAllFromApprovedPropsWithCount";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
conn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read()) {
//do the reading
}
conn.Close();
}
}
我的代码中有几个这样的操作。所以,我正在考虑将它们转换为异步。
但另一方面,我看不到这种方法有多大吸引力(也许我没有看到正确的方向,谁知道呢!)。
那么,在这里使用这种新的异步编程模型有什么缺点吗?
编辑:
假设我重构代码如下:
public async Task<IEnumerable<Foo>> GetDataAsync() {
List<Foo> foos = new List<Foo>();
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString;
using (var conn = new SqlConnection(connectionString)) {
using (var cmd = new SqlCommand()) {
cmd.Connection = conn;
cmd.CommandText = "sp$DetailsTagsGetAllFromApprovedPropsWithCount";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
conn.Open();
var reader = await cmd.ExecuteReaderAsync();
while (reader.Read()) {
//do the reading
//create foos
}
conn.Close();
}
}
return foos;
}
据我对 await 关键字的理解,它将其后的代码转换为延续。此外,当它遇到 await 关键字时,它会立即返回其调用者,而不管操作状态如何。当它完成时,它会返回并触发继续代码。
这就是我的想法。
最佳答案
在这一点上我不同意 Ricka。异步数据库命令不仅很好,而且对于实现规模、吞吐量和延迟也很关键。他对线程池启动时间的反对意见仅适用于流量较低的 Web 服务器。
在高流量情况下(这是唯一重要的情况),线程池不必等待“注入(inject)”新线程。异步执行 SQL 命令不仅从 Web 服务器请求/线程健康的角度来看很重要,而且从总请求生命周期/延迟的角度来看也很重要:不相关的数据库调用可以并行执行,而不是顺序执行。仅此一项通常就会显着改善用户体验到的 HTTP 请求的延迟。换句话说,您的页面加载速度更快。
不过有一点忠告:在启用 Asynchronous Processing=true
之前,SQL 命令不是真正的异步命令。在连接字符串上。虽然未设置(默认情况下未设置,编辑:从 .NET Framework < 4.5 开始。Asynchronous Processing
is no longer required )您对 BeginExecuteReader
的“异步”调用只不过是一个骗局,该调用将启动一个线程并阻止那个线程。当在连接字符串中启用真正的异步处理时,调用就是真正的异步,并且回调基于 IO 完成。
请注意:第一个结果返回客户端后,异步 SQL 命令即完成,信息消息也算作结果。
create procedure usp_DetailsTagsGetAllFromApprovedPropsWithCount
as
begin
print 'Hello';
select complex query;
end
您已经失去了异步的所有好处。 print
创建一个发送回客户端的结果,该结果完成异步命令并在客户端恢复执行并继续“reader.Read()”。现在 that 将阻塞,直到复杂查询开始产生结果。您问“谁将 print
放在程序中?” 但 print
可能伪装成其他东西,也许看起来像 INSERT
执行 而 首先发出 SET NOCOUNT ON
.
关于c# - 从 C# AsyncCTP 使用 ExecuteReaderAsync 的任何缺点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9432647/
我正在尝试使用异步模式来执行 SQL 命令并返回 DataTable。有人可以建议如何解决这个问题吗? 这是我的代码: private static async Task ExecuteAsy
我创建了一个 OracleUnitOfWork 和 Repository 类,如下所示: public class OracleUnitOfWork : IOracleUnitOfWork {
我有一个存储过程,它有时会在 SELECT 语句后返回异常。例如: BEGIN TRY SELECT EmployeeId, EmployeeName FROM dbo.abc
我有一个存储过程,如果没有错误,它可以返回 2 组结果。 第一组只是一个普通的select。 第二组包含错误代码和错误信息,这一组总是返回一行。由于没有错误,错误代码将为 0,错误消息将为空。 和 如
我正在使用 .NET Core 2.0。我有以下调用 IDbCommand.ExecuteReader 的函数 public async Task> ReadAllAsync( System.
我有这个由多个客户端进程共享的 SQL 服务器实例。我希望查询以尽可能少的时间完成。 假设一个调用需要从这个共享的 Sql Server 读取 1k 到 10k 条记录。我的自然选择是使用 Execu
我有以下函数,它允许我传入一个对象并用返回数据(如果有)填充该对象。 我修改了该函数,使其可以异步调用。 public static async Task MySQLReturnReader(stri
有一些文章表明异步数据库调用在 .NET 中不是一个好主意。 Should my database calls be Asynchronous? Should my database calls be
我需要通过 WebApi 从 Sql Server 流式传输 blob 数据。 我不想在 Web 服务器的内存中缓冲 blob 数据。 我有以下代码,但它不起作用 - 没有异常(exception)。
我是一名优秀的程序员,十分优秀!