【发布时间】:2012-08-30 17:17:00
【问题描述】:
我正在处理现有的应用程序。此应用程序从一个大文件中读取数据,然后在进行一些计算后,将数据存储在另一个表中。
但是执行此操作的循环(见下文)需要很长时间。由于文件有时包含 1,000 条记录,因此整个过程需要数天时间。
我可以用其他东西替换这个foreach 循环吗?我尝试使用Parallel.ForEach,它确实有帮助。我是新手,非常感谢您的帮助。
foreach (record someredord Somereport.r)
{
try
{
using (var command = new SqlCommand("[procname]", sqlConn))
{
command.CommandTimeout = 0;
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(…);
IAsyncResult result = command.BeginExecuteReader();
while (!result.IsCompleted)
{
System.Threading.Thread.Sleep(10);
}
command.EndExecuteReader(result);
}
}
catch (Exception e)
{
…
}
}
查看答案后,我删除了 Async 并使用如下编辑代码。但这并没有提高性能。
using (command = new SqlCommand("[sp]", sqlConn))
{
command.CommandTimeout = 0;
command.CommandType = CommandType.StoredProcedure;
foreach (record someRecord in someReport.)
{
command.Parameters.Clear();
command.Parameters.Add(....)
command.Prepare();
using (dr = command.ExecuteReader())
{
while (dr.Read())
{
if ()
{
}
else if ()
{
}
}
}
}
}
【问题讨论】:
-
两个想法 - 首先,你做错了异步,结果你很可能在循环中为许多项目睡觉。第二,你能在整个循环中重用SqlCommand对象,而不是每次都创建/销毁一个吗?
-
如果您告诉我们更多关于您想要完成的工作,我们可能会向您展示一个运行速度快几个数量级的 SQL 解决方案,并避免整个异步/并行业务完全。
-
@user1110790:您发布的代码充满了错误(并且仍然至少有一个),所以我已经清理了一下。我可以谦虚地建议,当您在 SO 上发帖时,请确保您的代码正常;否则,您可能只会让很多 cmets 专注于这一点,而不是关注实际问题。
-
题外话: 虽然我在这里同意其他人的观点,即您以错误的方式使用异步方法,但让我补充一点,您永远不应该像这样轮询
AsyncResult那个:while (!result.IsCompleted) Thread.Sleep(…);。相反,您应该这样做:result.AsyncWaitHandle.WaitOne();虽然这也会阻塞调用线程,但它不需要任何轮询;操作系统将在完成后唤醒调用线程。 -
@RobertHarvey ,所以这实际上是读取包含帐户信息及其在线使用的文件的服务的一部分。根据数据,我们正在计算总使用量并使用存储过程将该信息添加到 3 个表中。存储过程只是更新现有记录或插入新记录。这些表很小,仅包含 5 列。