C# 多线程编程
我已经编写了一个控制台应用程序,从EMp_Raw中获取前50条记录,其中包含empname、EMPDailLink、InsertedDate、parsedstatus,应该从客户网站转到员工的每个链接,通过html抓取,获取详细信息并保存到数据库。我每分钟都使用任务调度器运行此作业。我能够成功地做到这一点,但经理希望它是多线程的,以使它更快。下面是我尝试过的,我插入了最后一条记录50次,而不是50条唯一的记录C# 多线程编程,c#,multithreading,C#,Multithreading,我已经编写了一个控制台应用程序,从EMp_Raw中获取前50条记录,其中包含empname、EMPDailLink、InsertedDate、parsedstatus,应该从客户网站转到员工的每个链接,通过html抓取,获取详细信息并保存到数据库。我每分钟都使用任务调度器运行此作业。我能够成功地做到这一点,但经理希望它是多线程的,以使它更快。下面是我尝试过的,我插入了最后一条记录50次,而不是50条唯一的记录 namespace Emp_Detail { class detEmp
namespace Emp_Detail
{
class detEmp
{
private string empname;
private string empdetlink;
public detEmp()
{
}
public detEmp(String empname, String empdetlink)
{
this.empname = empname;
this.empdetlink = empdetlink;
}
public string getempname()
{
return empname;
}
public void setempname(string empname)
{
this.empname = empname;
}
public string getempdetlink()
{
return empdetlink;
}
public void setempdetlink(string empdetlink)
{
this.empdetlink = empdetlink;
}
}
class Program
{
static void Main(string[] args)
{
detEmp detail = new detEmp() { };
List<detEmp> d = new List<detEmp>();
Logger.info("Start Emp details at: "+ DateTime.Now);
try
{
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
connection.Open();
using (SqlCommand sqlCommandReader = connection.CreateCommand())
{
sqlCommandReader.CommandText = @"SELECT top 50 empname, empDetailLink, ParsedStatus,InsertedDate FROM [dbo].[Emp_Raw] (nolock)
Where ParsedStatus = 0 and InsertedDate between '2014-07-23 08:30:30.000' and '2014-07-23 08:35:30.000'
order by InsertedDate";
SqlDataReader sqlDataReader = sqlCommandReader.ExecuteReader();
if (sqlDataReader.HasRows)//completed
{
int count = 0;
while (sqlDataReader.Read())
{
string DetailLink = sqlDataReader["EmpDetailLink"] == null ? string.Empty : sqlDataReader["EmpDetailLink"].ToString();
string empname = sqlDataReader["empname"] == null ? string.Empty : sqlDataReader["empname"].ToString();
if (!string.IsNullOrEmpty(empname))
{
detail.setempname(empname);
detail.setempdetlink(DetailLink);
d.Add(detail);
}
}
}
}
}
//when I print DetailLink using for loop I can see only last record inserted 50 times--not sure why
var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 1 }; //Number of cores you have, limits the thread count
Parallel.ForEach(d, options, i =>
{
//THis is a function that pulls out emp info from client website and puts into our db using htmlagilitypack--tested thoroughly works fine
InsertDetails(i.getempname(), i.getempdetlink());
Thread.Sleep(50);
});
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
connection.Open();
using (SqlCommand sqlCommandReader = connection.CreateCommand())
{
sqlCommandReader.CommandText = ";WITH CTE AS (SELECT TOP 50 * FROM [dbo].[Emp_Raw] (nolock) where parsedstatus=0 and InsertedDate between '2014-07-23 08:30:30.000' and '2014-07-23 08:35:30.000' ORDER BY InsertedDate) UPDATE CTE SET ParsedStatus=1";
sqlCommandReader.ExecuteNonQuery();
}
}
}
您正在创建单个细节对象
detEmp detail = new detEmp() { };
…然后重新分配SQL reader循环中的内容
while (sqlDataReader.Read())
{
...
if (!string.IsNullOrEmpty(empname))
{
detail.setempname(empname);
detail.setempdetlink(DetailLink);
d.Add(detail);
}
换句话说,您可以将数据指定给详细信息,将其添加到集合中,更改详细信息的内容,然后再次添加。。。问题在于,将同一对象添加到列表中50次,最后都包含最后读取的行
您可以做的只是为每个迭代创建一个新的细节对象
if (!string.IsNullOrEmpty(empname))
{
detEmp detail = new detEmp() { };
detail.setempname(empname);
detail.setempdetlink(DetailLink);
d.Add(detail);
}
…这将在列表中为您提供50个不同的对象,每个对象都有各自的内容。您使用的是什么版本的C?顺便说一句,按照惯例,类名、getter和setter以及方法都是大写的。你能展示一下运行正常的原始版本吗?在原始代码中,我没有任何线程代码,如果!string.IsNullOrEmptyempname{InsertDetailsempname,DetailLink;}Iam正在使用.Net 4.5 framework。是否要加快代码速度?摆脱线程。睡觉。