正确的方法是什么?基本上,这种方法是将IO和CPU密集型任务组合到同一功能中并异步运行。最终,这超时了,但它无法联系数据库。我认为正在发生的事情是,由于线程数量众多,并且在建立MySQLConnection(即conn.Open)时,它挂在内部的Mysql.Data代码上,该代码正在等待TcpClient.ConnectAsync.Wait();。最终超时。进行此工作的唯一方法是减少创建的任务数。
我怀疑等待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();
}
最佳答案
正确的方法是打开连接,从数据库读取/写入数据库,关闭连接。然后,您可以进行CPU工作等,此时数据库连接已可用于其他功能。您的问题不在线程中,您的问题是两个任务(DB和计算)的交错。
换句话说,数据库连接是昂贵的资源。您在执行其他操作(其他占用大量CPU的工作)时,会占用此昂贵的资源。所有昂贵的资源都错了。
顺便说一句。您的并行方法本身是有问题的,但即使实现了这100个线程,如果您实现conn.Open
重试之类的方法,也应该有可能使其工作。如果失败,请稍后再试。即使在现实情况下,此“重试”也是有用的,因为该应用程序可以随时在网络上出现问题,并且您可以在几秒钟后通过重试保存它,而不是完全杀死任务。
关于c# - CPU/IO密集异步任务(mysql数据库连接失败),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57777325/