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