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

Parallel.ForeachSQL查询有时会导致Connection共享

时间:2023-04-10 18:27:51 C#

Parallel.ForeachSQL查询有时会导致Connection我需要在我的应用程序中加速执行12个查询。我从常规的foreach切换到Parallel.ForEach。但有时我会收到错误消息“ExecuteReader需要一个打开且可用的连接。连接的当前状态是连接。”我的理解是,由于12个查询中的许多查询使用相同的InitialCatalog,因此没有真正的新连接,这可能是问题所在?我怎么解决这个问题?“sql”是一个“Sql”类型的列表——这个类只是一个字符串名称、字符串连接和查询的列表。这是代码://////连接到SQL,执行所有查询并将结果存储在数据表列表中//////配置文件中每个查询的数据表列表publicListGetAllData(){Stopwatchsw=新秒表();sw.开始();列表数据=newList();列表sql=newList();sqlone=newSql();one.connection="DataSource=XXX-SQL1;InitialCatalog=XXXDB;IntegratedSecurity=True";one.name="Col1";one.queries.Add("SELECTNameFROM[Reports]");one.queries.Add("SELECTOtherFROM[Reports2]");sql.Add(一);sql2=newSql();two.connection="DataSource=XXX-SQL1;InitialCatalog=XXXDB;IntegratedSecurity=True";two.name="Col2";two.queries.Add("SELECTAlternateNameFROM[Reports1]");sql.Add(二);sql3=newSql();three.connection="DataSource=YYY-SQL2;InitialCatalog=YYYDB;IntegratedSecurity=True";三.name="Col3";three.queries.Add("从时间中选择频率");sql.Add(三);尝试{//ParallelOptionsoptions=newParallel选项();//选项.MaxDegreeOfParallelism=3;//Parallel.ForEach(sql,options,s=>Parallel.ForEach(sql,s=>//foreach(sqlsinsql){foreach(stringqins.queries){using(connection=newSqlConnection(s.connection)){connection.Open();DataTabledt=newDataTable();dt.TableName=s.name;command=newSqlCommand(q,connection);SqlDataAdapteradapter=newSqlDataAdapter();adapter.SelectCommand=command;adapter.Fill(dt);//adapter.Dispose();lock(data){data.Add(dt);}}}});}catch(Exceptionex){MessageBox.Show(ex.ToString(),"GetAllDataerror");}sw.Stop();MessageBox.Show(sw.Elapsed.ToString());returndata;}这是我制作的你需要的Sql类://////类定义SQL连接及其各自的查询///publicclassSql{//////连接/查询的名称///publicstringname{get;set;}//////SQL连接字符串///publicstringconnection{get;set;}//////连接的SQL查询列表///公共列表查询=newList();我会重构你的业务逻辑(连接到数据库)publicclassSqlOperation{publicSqlOperation(){Queries=newList();}publicstringTableName{get;放;}公共字符串ConnectionString{得到;放;}公共列表查询{get;放;}}publicstaticListGetAllData(IEnumerablesql){vartaskArray=sql.SelectMany(s=>s.Queries.Select(query=>Task.Run(()=>//Task.Factory.StartNewfor.NET4.0ExecuteQuery(s.ConnectionString,s.TableName,query)))).ToArray();尝试{Task.WaitAll(taskArray);}catch(AggregateExceptione){MessageBox.Show(e.ToString(),"GetAllData错误");}返回taskArray.Where(t=>!t.IsFaulted).Select(t=>t.Result).ToList();}publicstaticDataTableExecuteQuery(stringconnectionString,stringtableName,stringquery){DataTabledataTable=null;使用(varconnection=newSqlConnection(connectionString)){dataTable=newDataTable();dataTable.TableName=表名;using(varcommand=newSqlCommand(query,connection)){connection.Open();使用(变种适应ter=newSqlDataAdapter()){adapter.SelectCommand=command;适配器.填充(数据表);}}}返回数据表;Ado.Net有一个非常智能的连接池,所以通常你应该只打开连接和关闭每个命令的连接,让池处理它们是否实际打开或关闭,所以每个命令一个连接:Parallel.ForEach(sql,s=>//foreach(sqlsinsql){foreach(stringqins.queries){using(connection=newSqlConnection(s.connection)){connection.Open();DataTabledt=newDataTable();dt.TableName=s.name;command=newSqlCommand(q,connection);SqlDataAdapteradapter=newSqlDataAdapter();adapter.SelectCommand=command;adapter.Fill(dt);//adapter.Dispose();lock(data){data.Add(dt);}}}}也可以在connectionstring中使用MultipleActiveResultSets=true来支持多个reader以上是C#学习教程:Parallel.ForeachSQL查询有时会导致Connection共享的全部内容.多多关注—本文收集自网络,不代表立场,如涉及侵权,请点击右下角联系管理员删除。如有转载请注明出处: