c#多线程循环数据表

本文关键字:数据表 循环 多线程 | 更新日期: 2023-09-27 18:08:59

我有一个datatable1000 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;
        }

c#多线程循环数据表

您将在这里遇到数据表写操作的线程安全问题。因此,您需要确保所执行的操作是分开的。

好处是你实际上是在做三个不同的步骤,你可以很容易地把它们分开,并行化慢的部分,同时保持线程安全。

你的代码是这样做的:

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;
}

阻塞集合可以解决这个问题:

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
 }
}