C# 连接池&x2013;一个过程&x2013;多线程
我对连接池的理解是:;如果connectionstring完全相同,那么我们将重用该连接,而不是创建新连接 我的问题是,我正在为并行处理创建许多线程。在这个“虚拟”程序中,我创建了500个线程,并让ThreadPool函数处理这些线程 这些步骤是:C# 连接池&x2013;一个过程&x2013;多线程,c#,sql-server,multithreading,connection-pooling,invalidoperationexception,C#,Sql Server,Multithreading,Connection Pooling,Invalidoperationexception,我对连接池的理解是:;如果connectionstring完全相同,那么我们将重用该连接,而不是创建新连接 我的问题是,我正在为并行处理创建许多线程。在这个“虚拟”程序中,我创建了500个线程,并让ThreadPool函数处理这些线程 这些步骤是: 每个线程在SQL中生成一个更新表。(说明更新的时间戳) 然后线程休眠1到10秒(随机) 最后,线程在SQL中进行另一次更新(说明结束时间的时间戳) 然后线程退出 class Program { static void Main(string[
class Program
{
static void Main(string[] args)
{
int numberOfThreads = 150;
ThreadPool.SetMinThreads(numberOfThreads, numberOfThreads);
ThreadPool.SetMaxThreads(numberOfThreads, numberOfThreads);
List<Int64> chunkList = new List<Int64>();
int maxNumberOfChunks = 500;
for (int i = 1; i < maxNumberOfChunks; i++)
{
chunkList.Add(i);
}
foreach (Int64 chunk_id in chunkList)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadWorker), new arguments { chunk_id = chunk_id });
}
Console.ReadLine();
}
static void ThreadWorker(Object stateInfo)
{
arguments arguments = (arguments)stateInfo;
Console.WriteLine("Chunk # : {0} is set to START", arguments.chunk_id);
UpdateSQLdb(arguments.chunk_id, DateTime.Now, null, null, "START", null, null);
Random random = new Random();
int mseconds = random.Next(1, 10) * 1000;
System.Threading.Thread.Sleep(mseconds);
Console.WriteLine("Chunk # : {0} is sleeping for {1} sec.", arguments.chunk_id, mseconds);
Console.WriteLine("Chunk # : {0} ist set to END", arguments.chunk_id);
UpdateSQLdb(arguments.chunk_id, null, DateTime.Now, null, "END", null, null);
}
struct arguments
{
public Int64 chunk_id;
}
static void UpdateSQLdb(Int64 CHUNK_ID, DateTime? START_TS = null, DateTime? END_TS = null, Enum CHUNK_STATUS = null, string error_messages = null, byte? NEW_CALCULATION_ATTEMPTS = null, byte? NEW_POSTPROCESS_ATTEMPTS = null)
{
using (SqlConnection conn = new SqlConnection("Data Source=C55S01;Initial Catalog=MCS_BATCH;Integrated Security=SSPI;Asynchronous Processing=True")) //Timeout=60;Max Pool Size=200;Pooling=True;
{
int result = -1;
conn.Open(); //<-- Each time I open a connection. It creates a new instead of reusing one from the ConnectionPool
try
{
using (SqlCommand cmd = new SqlCommand("TEST.UpdateSQL", conn))
{
cmd.CommandTimeout = 300;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("@CHUNK_ID", SqlDbType.BigInt, 15).Value = CHUNK_ID;
cmd.Parameters.Add("@START_TS", SqlDbType.DateTime2, 7).Value = START_TS;
cmd.Parameters.Add("@END_TS", SqlDbType.DateTime2, 7).Value = END_TS;
cmd.Parameters.Add("@ERR_MESSAGE", SqlDbType.VarChar).Value = error_messages;
cmd.Parameters.Add("@ReturnValue", System.Data.SqlDbType.Int, 4).Direction = System.Data.ParameterDirection.ReturnValue;
try
{
result = cmd.ExecuteNonQuery();
int return_value = (int)cmd.Parameters["@ReturnValue"].Value;
if (return_value != 0)
{
Console.WriteLine("1. Error in running TEST.UpdateSQL, return value is : {0}", cmd.Parameters["@ReturnValue"].Value);
}
}
catch (SqlException ex)
{
UpdateSQLdb(CHUNK_ID, null, DateTime.Now, null, ex.Message.ToString(), null, null);
Console.WriteLine("2. Error executing TEST.UpdateSQL : {0}", ex);
}
}
}
catch (Exception ex)
{
Console.WriteLine("3.Error in TEST.UpdateSQL : {0}", ex);
throw;
}
if (conn.State == ConnectionState.Open)
{
Console.WriteLine("Closing connection....");
conn.Close();
}
conn.Dispose();
}
}
}
类程序
{
静态void Main(字符串[]参数)
{
int numberOfThreads=150;
SetMinThreads(numberOfThreads,numberOfThreads);
SetMaxThreads(numberOfThreads,numberOfThreads);
List chunkList=新列表();
int maxNumberOfChunks=500;
for(int i=1;i conn.Open();//它正在执行您要求它执行的操作。它正在使用池中的连接,但您给了它太多的工作。如果您有500个线程和200个连接,则每个线程都不能有一个连接。您可能应该有与线程一样多的连接
如果您还有更多的工作要做(所有500个线程都很忙),那么您必须要么向使用者返回一个错误,要么限制应用程序的输入。您正试图在100个连接上运行500个并发进程。您认为这怎么可能?SQL连接池不能运行两个(或三个或四个)在同一连接上同时执行不同的命令。这不是连接池的意思。无论如何,您的网络连接实际上不太可能有能力满足那么多并发请求。您几乎可以肯定不应该有那么多线程或那么多连接,除非这是一个有很多线程的大型服务器f资源备份。这是一个很好的问题。使用后您将安全地处理连接。您对连接对象的使用仅限于一次调用的持续时间。池应该可以正常工作。从池中获取连接会超时。如果没有可用连接,则不会明显失败。这应该可以正常工作如果所有连接都保持一段时间。调查,为什么连接保持很长时间。无关:你使用的是迷信的处置模式。处置三次而不是一次没有任何好处。