收到的完整错误是:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
所以我有一个平行的foreach:
Parallel.ForEach(fields, item =>
{
item.SysInvoiceID = _destinationRepo.GetMySQLSystemID(item);
});
调用一个如下所示的方法:
public int GetMySQLSystemID(CustomFieldBase GenericCustomField)
{
CustomField customField = GenericCustomField as CustomField;
int sys_InvoiceID = 0;
using (MySqlConnection mySQLConnection = new MySqlConnection("Server=web01;Database=wmp;User Name=root;Password=TotallyMyPWord"))
{
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.CommandText = $@"SELECT Sys_InvoiceID FROM tblsys_naturalkey_lu WHERE CompanyCode = '{customField.CompanyCode}' AND InvoiceNo = '{customField.InvoiceNo}'
AND LineItemNo = '{customField.LineItemNo}' AND FiscalYear = '{customField.FiscalYear}'";
cmd.CommandType = CommandType.Text;
cmd.Connection = mySQLConnection;
mySQLConnection.Open();
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
sys_InvoiceID = (int)reader["Sys_InvoiceID"];
}
}
mySQLConnection.Close();
}
}
return sys_InvoiceID;
}
在查看MySQL会话管理器时,我可以看到Parallel.ForEach
在我达到限制之前不断添加连接。
我关闭了我的MySQLConnection,为什么它一直在创建连接直到最大限制?
答案 0 :(得分:0)
您对Parallel.ForEach()
创建的并行操作数量没有任何限制,因此它将创建无限数量的SQL连接。
您可以通过specifying the maximum degree of parallelism:
解决此问题Parallel.ForEach(fields, new ParallelOptions { MaxDegreeOfParallelism = 8 }, item =>
{
item.SysInvoiceID = _destinationRepo.GetMySQLSystemID(item);
});
然而(正如其他人所指出的那样),在任何情况下,你都不应该使用Parallel.ForEach()
进行IO绑定工作。
答案 1 :(得分:0)
您可以使用SqlConnection.ClearPool方法,但如果必须通过并行循环执行此操作,我仍建议重用您的连接。正如其他人所说,你不应该这样做。
例如,在启动并行循环之前打开连接。一切都完成后再处理。