C# CPU/IO密集型异步任务(mysql数据库连接失败)
正确的方法是什么。基本上,这种方法是将IO和CPU密集型任务组合到同一个函数中,并异步运行它。最终,它会超时,出现一个异常,即它无法联系数据库。我认为正在发生的事情是,由于线程数量太多,当MySQLConnection(ie conn.Open)建立时,它挂在等待TcpClient.ConnectAsync.Wait()的内部Mysql.Data代码上;最终会超时。唯一可行的方法是减少创建的任务数量C# CPU/IO密集型异步任务(mysql数据库连接失败),c#,mysql,asynchronous,C#,Mysql,Asynchronous,正确的方法是什么。基本上,这种方法是将IO和CPU密集型任务组合到同一个函数中,并异步运行它。最终,它会超时,出现一个异常,即它无法联系数据库。我认为正在发生的事情是,由于线程数量太多,当MySQLConnection(ie conn.Open)建立时,它挂在等待TcpClient.ConnectAsync.Wait()的内部Mysql.Data代码上;最终会超时。唯一可行的方法是减少创建的任务数量 我怀疑等待ConnectAsync失败是因为它不能被授予线程 public runtest()
我怀疑等待ConnectAsync失败是因为它不能被授予线程
public runtest() {
var tasks = new List<Task>();
for (int i = 0; i < 100; i++)
{
tasks.Add(Task.Run(() =>
{
string connStr = "server=localhost;user=root;database=***********;port=3306;password=*********";
MySqlConnection conn = new MySqlConnection(connStr);
try
{
conn.Open();
//simulate some CPU work
Thread.Sleep(5000);
conn.Close
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
}
}));
}
var taskarray = tasks.ToArray();
Task.WhenAll(taskarray).Wait();
}
公共运行测试(){
var tasks=新列表();
对于(int i=0;i<100;i++)
{
tasks.Add(Task.Run)(()=>
{
string connStr=“server=localhost;user=root;database=************;port=3306;password=**********”;
MySqlConnection conn=新的MySqlConnection(connStr);
尝试
{
conn.Open();
//模拟一些CPU工作
睡眠(5000);
关闭连接
}
捕获(例外情况除外){
Console.WriteLine(例如ToString());
}
}
}));
}
var taskarray=tasks.ToArray();
Task.WhenAll(taskarray.Wait();
}
正确的方法是打开连接,从数据库读/写,关闭连接。然后你可以做你的CPU工作,等等。此时DB连接已经可以用于其他东西了。您的问题不在线程中,您的问题是两个任务(数据库和计算)的交错
换句话说,数据库连接是一种昂贵的资源。您在做其他事情(其他CPU密集型工作)的同时持有这一昂贵的资源。这对于所有昂贵的资源来说都是错误的
顺便说一句,您的并行方法本身是有问题的,但即使使用这100个线程,如果您实现了类似于重试
conn.Open
的功能,也应该可以使其工作。如果失败,请稍后重试。这种“重试”即使在现实场景中也很有用,因为应用程序随时可能在网络上出现问题,您可以在几秒钟后重试保存它,而不是完全终止任务。正确的方法是打开连接、从/到数据库读/写、关闭连接。然后你可以做你的CPU工作,等等。此时DB连接已经可以用于其他东西了。您的问题不在线程中,您的问题是两个任务(数据库和计算)的交错
换句话说,数据库连接是一种昂贵的资源。您在做其他事情(其他CPU密集型工作)的同时持有这一昂贵的资源。这对于所有昂贵的资源来说都是错误的
顺便说一句,您的并行方法本身是有问题的,但即使使用这100个线程,如果您实现了类似于重试
conn.Open
的功能,也应该可以使其工作。如果失败,请稍后重试。这种“重试”即使在现实场景中也很有用,因为应用程序随时可能在网络上出现问题,您可以在几秒钟后重试保存它,而不是完全终止任务。“我怀疑等待ConnectAsync失败是因为无法授予它线程?”可能;NET线程池需要一段时间才能创建您需要的100个线程。这也可能是因为连接字符串中的MaxPoolSize
默认为100,并且池中的所有连接都很忙,因此代码正在等待释放连接。最后请注意,如果您想执行任何异步DB操作,MySql.Data不支持它们:请改为“切换到”。我怀疑等待ConnectAsync失败是因为它无法被授予线程吗;NET线程池需要一段时间才能创建您需要的100个线程。这也可能是因为连接字符串中的MaxPoolSize
默认为100,并且池中的所有连接都很忙,因此代码正在等待释放连接。最后请注意,如果要执行任何异步DB操作,MySql.Data不支持它们:请改为切换到。