当前位置: 首页 > 编程语言 > C#

我可以使用Parallel.For和sql命令吗?分享

时间:2023-04-10 19:46:29 C#

我可以将Parallel.For与sql命令一起使用吗?我有一个班级范围publicclassavl_range{publiclongstart{get;放;}公共长端{得到;放;如果我使用正常的FOR它工作得很好,但必须等待每个命令完成,每个查询需要8秒,所以10个查询需要80秒。在并行版本中,如果我只打印范围,它会完美运行,但如果我尝试执行命令,它会说已经在进行中。{“一个操作已经在进行中。“}我该如何解决?varnumbers=newList();使用(varconn=newNpgsqlConnection(strConnection)){conn.Open();ActionforEachLoop=number=>//开始定义forLoop{//只有控制台写入行工作正常Console.WriteLine(number.start+"-"+number.end);使用(varcmd=newNpgsqlCommand()){cmd.Connection=conn;cmd.CommandText=String.Format("SELECT*FROMavl_db.process_near_link({0},{1});",number.start,number.end);//这里导致错误。使用(varreader=cmd.ExecuteReader()){while(reader.Read()){Console.WriteLine(reader.GetString(0));}}}};Parallel.ForEach(数字,forEachLoop);});Npgsql连接——在任何给定时间点只能运行一个命令(换句话说,不支持MARS)。打开多个连接以并行执行查询当然是有意义的。虽然建立新的物理连接代价高昂,但是连接池是非常轻量级的,所以重用一个物理连接的开销很小。不这样做的主要原因是如果您需要在同一个事务中执行多个操作。即使您可以使用MARS,连接对象几乎也不是线程安全的,您需要为每个线程建立连接。Parallel.ForEach具有重载以简化此操作,它具有在线程开始和结束时运行的函数。varnumbers=newList();FunclocalInit=>()=>{varconn=newNpgsqlConnection(strConnection);conn.Open();};动作localFinally=(conn)=>conn.Dispose();FuncforEachLoop=(number,loopState,conn)=>//开始定义forLoop{//只有控制台写行工作正常Console.WriteLine(number.start+"-"+number.end);使用(varcmd=newNpgsqlCommand()){cmd.Connection=conn;cmd.CommandText=String.Format("SELECT*FROMavl_db.process_near_link({0},{1});",number.start,number.end);//这里导致错误。使用(varreader=cmd.ExecuteReader()){while(reader.Read()){控制台。WriteLine(读者。GetString(0));}}}返回连接;};平行线。ForEach(数字,localInit,forEachLoop,localFinally);话虽这么说,大多数时候与数据库的并发连接不是正确的想法,瓶颈可能在其他地方,您应该使用分析器来查看真正减慢您的程序的原因,并集中精力。评论示例代码:以上是C#学习教程:Parallel.For和sql命令可以使用吗?分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——varnumbers=GetDataForNumbers();列表结果=newList();Func>localInit=>()=>newList();Func,List>forEachLoop=(number,loopState,localList)=>//开始定义forLoop{using(varconn=newNpgsqlConnection(strConnection)){conn.Open();//这一行会让你的程序变慢很多,所以我把它注释掉了。//Console.WriteLine(number.start+"-"+number.end);使用(varcmd=newNpgsqlCommand()){cmd.Connection=conn;cmd.CommandText=String.Format("SELECT*FROMavl_db.process_near_link({0},{1});",number.start,number.end);using(varreader=cmd.ExecuteReader()){while(reader.Read()){//添加一个对象到线程局部列表,这里不需要加锁,因为我们是唯一可以访问它的线程.localList.Add(reader.GetString(0));}}}}返回本地列表;};行动>localFinally=localList=>{//C将本地列表与主要结果相结合,我们需要在此处锁定,因为一次可以合并多个线程。锁定(结果){结果。AddRange(本地列表);}};Parallel.ForEach(数字,localInit,forEachLoop,localFinally);//results现在包含来自此处所有线程的字符串。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: