【问题标题】:Properway to dispose of class in Parallel.Foreach在 Parallel.Foreach 中处理类的正确方法
【发布时间】:2012-04-19 16:36:28
【问题描述】:

我有一个简单的 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");
            }
        });

【问题讨论】:

    标签: c#


    【解决方案1】:

    如果 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");
            }
        }
    

    【讨论】:

    • 好的,让我提出一个新的愚蠢问题,我怎么知道或如何使课程一次性
    • 它不需要是一次性的,除非它包含对其他一次性类型的实例或非托管资源的引用。类的方法也需要处理它们创建的任何一次性对象。搜索 IDisposable/Disposable 模式。
    • 所以基本上是 WebSiteCrawlerClass() : IDisposable
    • 是的,但是除非您正确使用,否则仅添加 Dispose 方法将无济于事。
    【解决方案2】:

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

    【讨论】:

    【解决方案3】:

    您想要做的是为每个线程创建一个 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(); })。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-30
      • 1970-01-01
      • 2010-12-08
      • 2011-02-28
      • 2016-01-15
      • 1970-01-01
      相关资源
      最近更新 更多