我想为连接字符串实现多线程,它将从文件中检索更多的连接字符串,但它需要花费很多时间,所以我想使用多线程。以下是代码:
namespace ConsoleApplication1
{
public class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.WithTPLAndParallelOptions();
}
private object threadLock = new object();
public void ConnectDBAndExecuteQueryWithLock(string connectionString)
{
lock (threadLock)
{
try
{
string mysqlQuery = "SELECT PS_CD,COUNT(*) AS OFFLINE_FIR_COUNT FROM t_fir_registration WHERE state_cd=18 AND lang_cd=99 GROUP BY PS_CD";
//string connectionString = @"Server=.\SQLEXPRESS;Database=AUTODATA;Password=abc@123;User ID=sa";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
using (MySqlCommand command = new MySqlCommand(mysqlQuery, connection))
{
command.CommandTimeout = 80;
command.ExecuteNonQuery();
Console.WriteLine("Executed Thread.. " + Thread.CurrentThread.Name);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
public void WithTPLAndParallelOptions()
{
string cctns_offline_DBConnectionString = ConfigurationManager.ConnectionStrings["cctns_offline_DBConnectionString"].ConnectionString;
string[] filePaths = Directory.GetFiles(ConfigurationManager.AppSettings["filePath"].ToString(), "*.properties",
SearchOption.TopDirectoryOnly);
int ThreadCount = filePaths.Length;
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 5;
//Create Parallel.For to execute the task
Parallel.For(0, ThreadCount, options, i =>
{
foreach (string fileName in filePaths)
{
// i = i + 1;
// Read a text file using StreamReader
using (System.IO.StreamReader sr = new System.IO.StreamReader(fileName))
{
String line;
while ((line = sr.ReadLine()) != null)
{
if (line.StartsWith("db.url"))
{
string[] PS_CD = fileName.Split(new[] { "\\", ".", "_" }, StringSplitOptions.None);
string[] ip_address = line.Split(new[] { ";", "//", "/", ":" }, StringSplitOptions.None);
if (ip_address[3].ToString() != string.Empty && ip_address[3] != "SQL2K8CLUSTER")
{
string connstringrpl = cctns_offline_DBConnectionString.Replace("PS_IP", ip_address[3].ToString());
ConnectDBAndExecuteQueryWithLock(connstringrpl);
}
}
}
}
}
});
}
}
}
答案 0 :(得分:1)
1)目前您的Parallel.For
和foreach
循环是嵌套的,这意味着外部Parallel.For
循环的每次迭代都将重新执行内部foreach
循环的所有迭代。因此,如果您有10个文件,ConnectDBAndExecuteQueryWithLock()
将被执行10 * 10 = 100次,这可能不是您想要的,使您的程序慢得多。要解决此问题,请通过替换
foreach
循环
foreach (string fileName in filePaths)
{
...
}
与
{
var fileName = filePaths[i];
...
}
2)正如Jaya所指出的,lock (threadLock)
导致一次只有一个线程可以执行数据库查询,使您的多线程程序几乎是单线程的。由于lock
中的代码不使用任何共享变量,因此可以安全地完全删除lock
。