1

我有一个简单的 Parallel.Foreach 循环,在 DataTable 中有大约 1000 行,这些行中的每一个都调用一个新类,但是,内存会不断增加,直到内存不足。我想知道你如何正确地处理一个关于并行的新类。如果您说的是一个新手问题,那是因为并行和线程对我来说是新的。

  var options = new ParallelOptions();
        options.MaxDegreeOfParallelism = 5;
        Parallel.ForEach(urlTable.AsEnumerable(),options, drow =>
        {
            WebSiteCrawlerClass WCC = new WebSiteCrawlerClass();
            if (drow.ItemArray[0].ToString().Contains("$"))
            {

                WCC.linkGrabberwDates(drow.ItemArray[0].ToString(), "www");
            }
            else
            {
                WCC.NoDatesCarCrawler(drow.ItemArray[0].ToString(), "www");
            }
        });
4

3 回答 3

0

如果 WebSiteCrawlerClass 是一次性的,那么你会这样做

    using( var WCC = new WebSiteCrawlerClass() )
    {
        if (drow.ItemArray[0].ToString().Contains("$"))
        {
            WCC.linkGrabberwDates(drow.ItemArray[0].ToString(), "www");
        }
        else
        {
            WCC.NoDatesCarCrawler(drow.ItemArray[0].ToString(), "www");
        }
    }
于 2012-04-05T22:52:38.187 回答
0

使用异步而不是并行可以更好地解决此类问题。发出所有请求,并在它们返回给您时对其进行处理。只是一个想法。

于 2012-04-05T23:07:14.773 回答
0

您要做的是为每个线程创建一个 WebSiteCrawlerClass 对象,而不是为每个循环初始化一个对象。这可以使用Parallel.ForEach的“localInit”重载来完成。就像是:

    var options = new ParallelOptions();
    options.MaxDegreeOfParallelism = 5;
    Parallel.ForEach(urlTable.AsEnumerable(),
      options,
      () => new WebSiteCrawlerClass(),
      (drow, dummyLoopState, WCC) =>
      {
        if (drow.ItemArray[0].ToString().Contains("$"))
        {
            WCC.linkGrabberwDates(drow.ItemArray[0].ToString(), "www");
        }
        else
        {
            WCC.NoDatesCarCrawler(drow.ItemArray[0].ToString(), "www");
        }
        return WCC;
      },
      (wcc) => { } );

这假设您的 WebSiteCrawlerClass 对象是可重用的。如果您需要重置其状态或其他内容,请在最后的 finally 委托期间完成(就像(wcc) => { wcc.Reset(); }在最后一样)。

于 2012-04-05T23:45:22.367 回答