我有datatable
1000 records
。每行都有一个带链接的列。我将使用datatable
中的链接循环datatable
并从网站获取记录。代码工作正常,但这需要花费太多时间来检索记录。所以我需要在多个线程中传递它并获取记录并将所有记录添加到单个datatable
。我使用C# , Visual studio 2015
。
我们如何使用threading C#
,任何帮助表示赞赏。
现有代码如下。
for (int i = 0; i < dt.Rows.Count; i++)
{
String years = String.Empty;
dt.Rows[i]["Details"] = GetWebText(dt.Rows[i]["link"].ToString());
}
private String GetWebText(String url)
{
var html = new HtmlAgilityPack.HtmlDocument();
string text= html.LoadHtml(new WebClient().DownloadString(url));
return text;
}
答案 0 :(得分:0)
您将使用数据表的写操作的线程安全性来处理这里的问题。所以你需要确保你执行的操作分离得很好。
好处是你实际上正在做三个不同的步骤,你可以很容易地将它们分开并并行化慢速部分,同时保持线程安全。
以下是您的代码正在执行的操作:
var url = dt.Rows[i]["link"].ToString();
var webText = GetWebText(url);
dt.Rows[i]["Details"] = webText;
让我们处理这三个步骤中的数据,但只是平行GetWebText
部分。
这是:
var data =
dt
.AsEnumerable()
.Select(r => new { Row = r, Url = r["link"].ToString() })
.AsParallel()
// This `Select` is the only part run in parallel
.Select(x => new { x.Row, WebText = GetWebText(x.Url) })
.ToArray();
foreach (var datum in data)
{
datum.Row["Details"] = datum.WebText;
}
答案 1 :(得分:-1)
阻止收藏可以解决问题:
Blocking<string> links= new BlockingCollection<string>();\\ using System.Collections.Concurrent;
Blocking<string> results= new BlockingCollection<string>();
public static void main()
{
//get your datatable
for (int i = 0; i < dt.Rows.Count; i++)
{
ThreadStart t = new ThreadStart(threads);
Thread th = new Thread(t);
th.Start();
}
for (int i = 0; i < dt.Rows.Count; i++)
{
links.add(dt.Rows[i]["link"].ToString());
}
for (int i = 0; i < dt.Rows.Count; i++)
{
dt.Rows[i]["Details"] = results.Take();
}
}
public void threads()
{
while(true)
{
string url= Links.take();//block if links is empty
var html = new HtmlAgilityPack.HtmlDocument();
string text= html.LoadHtml(new WebClient().DownloadString(url));
results.add(text);//add result to the other queue
}
}