【发布时间】:2016-05-20 22:41:26
【问题描述】:
当存储过程 SelectNewObjects 返回很少 (~500) 条记录时,以下 SqlCommand 工作正常,没有明显的性能问题。但是,当它返回超过 1,000 条记录时,我开始遇到性能问题:
using (SqlCommand cmdAddNewObject = new SqlCommand("SelectNewObjects", con))
{
cmdAddNewObject.CommandType = CommandType.StoredProcedure;
cmdAddNewObject.Parameters.AddWithValue("@parameter1", parameter1);
using (SqlDataReader rdrAddNewObject = cmdAddNewObject.ExecuteReader())
{
while (rdrAddNewObject.Read())
{
if (rdrAddNewObject.GetString(0) != null)
{
try
{
addObject(parameter1, rdrAddNewObject.GetString(0), rdrAddNewObject.GetString(0).Length / 4, rdrAddNewObject.GetString(0).Substring(0, 2),
rdrAddNewObject.GetString(0).Substring(2, 2), rdrAddNewObject.GetString(1));
if (rdrAddNewObject.GetString(1) == "No description found")
{
// Do something
}
else
{
// Do something else
}
}
catch (Exception ex)
{
// Throw exception
}
}
}
}
}
简单来说,我在这里所做的就是为 SelectNewObjects 返回的每条记录调用一个方法 (addObject)。
几个细节:
SelectNewObjects 返回从 Table1 创建的临时表中的记录。
在 if / else 块中,我正在更新 addObjectTable1 字段/strong> 完成。
addObject 方法通过使用 SOA(面向服务的体系结构)将 SQL 临时表中找到的每条记录插入到单独的 Oracle 系统中。我没有被授予访问底层数据库的权限,所以我不得不接受这种做事方式。
有时临时表预计会有超过 20,000 条记录(每个只有两个字段:Name 和 Description),所以这很快就会变成一场噩梦。
在某一时刻,应用程序池将失败并出现以下两个错误(取自 IIS 7 Windows 事件查看器):
事件 ID 5013: 服务应用程序池“.NET v4.5”的进程在关闭期间超出了时间限制。进程 ID 为“5616”。
事件 ID 5138: 为应用程序池“.NET v4.5”服务的工作进程“5616”未能停止协议“http”的侦听器通道 分配的时间。数据字段包含错误号。
technet.microsoft.com 和 support.microsoft.com 中对这些事件 ID 的描述并未对这个性能问题提供太多的说明,并且对于其根本原因也不是结论性的。
也就是说,有没有什么方法可以改进 C# 代码以处理 SP 返回的数万条记录,并更快地对每条记录执行操作?
【问题讨论】:
-
如果确定是 C# 代码中的瓶颈?如果您要在 Management Studio 中执行相同的存储过程,时间安排是多少?
-
把问题一分为二:注释掉
while循环的内部,看看存储过程和数据检索时间是否可以接受。
标签: c# tsql iis-7 application-pool