我已经编写了一个控制台应用程序,它从EMp_Raw获得前50条记录(包含空名、empdetaillink、inseteddate、parsedstatus),并且应该转到客户端网站上的员工的每个链接,然后抓取它的详细信息并保存到我们的数据库中。我每分钟使用任务调度程序运行这个任务。我能够成功地做到这一点,但经理希望它是多线程的,以使它更快。下面是我尝试的,我是插入最后的记录50次,而不是50独特的记录。
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();
}
}
}发布于 2014-07-26 08:39:35
你正在创建一个单一的细节对象;
detEmp detail = new detEmp() { };然后,...and重新分配SQL循环中的内容;
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);
} ...which将在列表中给出50个不同的对象,每个对象都有各自的内容。
https://stackoverflow.com/questions/24969059
复制相似问题