c# - 如何在 foreach 循环中并行执行方法或 DML 以加快执行时间?
问题描述
我有以下代码查询表并更新其中的行,然后根据以前的查询执行插入:
private void button1_Click(object sender, EventArgs e)
{
doDBDML();
}
private void doDBDML()
{
using (ThreadingDBEntities db = new ThreadingDBEntities())
{
var rows = db.people.Where(x => x.id == null).ToList();
foreach (person p in rows) // how to execute it in parallel.
{
p.id = p.personID; // update null value.
// execute stored procedure which has output parameter to get id (return existing id or insert new row and get its id).
ObjectParameter outParam = new ObjectParameter("p_id", typeof(Int32));
db.sp_getCompanyId(p.company, outParam);
// and new row. this depends on current person object id , and company id which has returned from stored precedure.
User_Company userComp = new User_Company();
userComp.person_Id = p.personID;
userComp.Company_Id = (Int32) outParam.Value;
db.SaveChanges();
}
}
}
存储过程是
CREATE PROCEDURE [dbo].[sp_getCompanyId]
@p_ocmpany_Name nvarchar(255),
@p_id int output
AS
SELECT @p_id = id
from Company
where Company_name = @p_ocmpany_Name
if @p_id is null
begin
begin transaction;
insert into Company (company_name) values (@p_ocmpany_Name);
select @p_id = SCOPE_IDENTITY();
commit transaction;
end;
RETURN @p_id
这工作正常,但问题是: - 查询返回大量行,因此执行需要很长时间才能执行,如何加速它?如何调用上述 doDBDML 方法将其作为并行或批量执行来执行?
- 在大量行上执行应用程序时,它没有响应,如何解决这个问题?在后台或作为新线程运行它???
我的问题与 Windows 窗体应用程序有关,但是我也想知道该解决方案是否适用于 asp.net
解决方案
正如 TomC 和 TheGeneral 所说,您解决问题的解决方案可能有问题。如果您想检查通过简单的并行性可以获得多少速度,您可以查看
Parallel.Foreach
https://msdn.microsoft.com/de-de/library/dd460720(v=vs.100).aspx
但也要记住,如果您使用多个线程,您可能会在数据库中创建重复项。例如
Thread #1 - enters stored-procedure
Thread #1 - cannot find customer "customerA" -> start transaction for creating a new customer
Thread #2 - enters stored-procedure
Thread #2 - cannot find customer "customerA" -> start transaction
Thread #2 - finish transaction -> return id '42'
Thread #1 - finish transaction -> return id '666'
现在您有同一个客户的两个客户数据集
ID | Name
42 | customerA
666 | customerA
推荐阅读
- javascript - 创建一个名为 toQueryString 的函数
- c - 获取C中二维数组中的元素数
- javascript - Socket.io如何实现一个wss连接?
- translation - Microsoft 翻译服务的身份验证错误
- ios - SwiftUI 无法关闭呈现的第二张工作表
- python - python如何将代码更改为递归函数
- docker-compose - 如何在 Docker compose yaml 中定义事件中心?
- linux - 错误无法连接到zsys守护进程:连接错误:desc =“传输:拨号时出错拨号unix /run/zsysd.sock:
- sql - 更新列表中的多个条件
- python - 有没有办法编写程序可以接受任何文本文件而不管布局结构的代码?