在Parallel.Foreach中处理类的属性
本文关键字:属性 处理 Parallel Foreach | 更新日期: 2023-09-27 18:30:06
我有一个简单的Parallel.Foreach循环,它在DataTable中有大约1000行,这些行中的每一行都调用一个新的class,然而,内存会不断增加,直到我耗尽内存。我想知道你如何正确地处理一个关于平行类的新类。如果你说的是一个新手问题,那是因为并行和线程对我来说是新的
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");
}
});
如果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");
}
}
使用异步而不是并行可以更好地解决这类问题。分发所有的请求,并在它们返回给您时进行处理。只是一个想法。
您想要做的是为每个线程创建一个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(); }
)。