[英]multithreaded programming c#
我編寫了一個控制台應用程序,該應用程序從EMp_Raw中獲取前50條記錄(包含empname,empdetaillink,inseteddate,parsedstatus),並且應轉到客戶網站上員工的每個鏈接並通過html進行爬網,並獲取其詳細信息並將其保存到我們的數據庫中。我每分鍾使用任務計划程序運行此作業。 我能夠成功地做到這一點,但經理希望它具有多線程功能以使其更快。 下面是我嘗試過的方法,我將最后一條記錄插入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();
}
}
}
您正在創建一個細節對象。
detEmp detail = new detEmp() { };
...然后在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);
}
...這將為您提供列表中的50個不同的對象,每個對象都有各自的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.