C# 使用Parallel.ForEach和;Task.Factory.StartNew
我正在开发一个asp.net mvc-4 web应用程序。。但我不确定在列表上使用这两种方法进行迭代和启动WebClient()调用之间有什么区别:- 方法1C# 使用Parallel.ForEach和;Task.Factory.StartNew,c#,asp.net,.net,asp.net-mvc,parallel-processing,C#,Asp.net,.net,Asp.net Mvc,Parallel Processing,我正在开发一个asp.net mvc-4 web应用程序。。但我不确定在列表上使用这两种方法进行迭代和启动WebClient()调用之间有什么区别:- 方法1 Parallel.ForEach(photos,new ParallelOptions { MaxDegreeOfParallelism = 7 }, p => { ResourceAccountListInfo resourceAccountListInfo
Parallel.ForEach(photos,new ParallelOptions { MaxDegreeOfParallelism = 7 }, p =>
{
ResourceAccountListInfo resourceAccountListInfo = new ResourceAccountListInfo();
WebClient wc = new WebClient();
var json = wc.DownloadString(p.url);
resourceAccountListInfo = JsonConvert.DeserializeObject<ResourceAccountListInfo>(json);
if (resourceAccountListInfo.operation.Details.CUSTOMFIELD.Count > 0)
{
List<CUSTOMFIELD> customfield = resourceAccountListInfo.operation.Details.CUSTOMFIELD.Where(a =>
a.CUSTOMFIELDLABEL.ToLower() == "name"
).ToList();
if (customfield.Count == 1)
{
PMresourcesOnly.Add(resourceAccountListInfo.operation.Details);
}
}
//code goes here
});
Parallel.ForEach(照片,新的并行选项{MaxDegreeOfParallelism=7},p=>
{
ResourceAccountListInfo ResourceAccountListInfo=新的ResourceAccountListInfo();
WebClient wc=新的WebClient();
var json=wc.DownloadString(p.url);
resourceAccountListInfo=JsonConvert.DeserializeObject(json);
如果(resourceAccountListInfo.operation.Details.CUSTOMFIELD.Count>0)
{
List customfield=resourceAccountListInfo.operation.Details.customfield.Where(a=>
a、 CUSTOMFIELDLABEL.ToLower()=“名称”
).ToList();
如果(customfield.Count==1)
{
PMresourcesOnly.Add(resourceAccountListInfo.operation.Details);
}
}
//代码在这里
});
方法2
foreach (Photo p in photos)
{
Task.Factory.StartNew(() =>
{
ResourceAccountListInfo resourceAccountListInfo = new ResourceAccountListInfo();
WebClient wc = new WebClient();
var json = wc.DownloadString(p.url);
resourceAccountListInfo = JsonConvert.DeserializeObject<ResourceAccountListInfo>(json);
if (resourceAccountListInfo.operation.Details.CUSTOMFIELD.Count > 0)
{
List<CUSTOMFIELD> customfield = resourceAccountListInfo.operation.Details.CUSTOMFIELD.Where(a =>
a.CUSTOMFIELDLABEL.ToLower() == "name"
).ToList();
if (customfield.Count == 1)
{
PMresourcesOnly.Add(resourceAccountListInfo.operation.Details);
}
}
//code goes here
});
}
foreach(照片中的照片p)
{
Task.Factory.StartNew(()=>
{
ResourceAccountListInfo ResourceAccountListInfo=新的ResourceAccountListInfo();
WebClient wc=新的WebClient();
var json=wc.DownloadString(p.url);
resourceAccountListInfo=JsonConvert.DeserializeObject(json);
如果(resourceAccountListInfo.operation.Details.CUSTOMFIELD.Count>0)
{
List customfield=resourceAccountListInfo.operation.Details.customfield.Where(a=>
a、 CUSTOMFIELDLABEL.ToLower()=“名称”
).ToList();
如果(customfield.Count==1)
{
PMresourcesOnly.Add(resourceAccountListInfo.operation.Details);
}
}
//代码在这里
});
}
感谢并行。ForEach提供了一种在集合中迭代的便利。 尽管可以在循环中调用
Task.Factory.StartNew
,但它本身并没有任何东西表明它将在循环中使用。你可以只开始一项任务
由于Parallel.ForEach
假定一组并行操作,因此它为您提供了ParallelOptions
,允许您指定该循环范围内的并发操作数。这很有用,因为在某些情况下,我们可能不关心有多少并发操作,但在其他情况下,我们可能会关心。看看哪个描述了使用信号量来限制并发任务的数量。设置MaxDegreeOfParallelism
比使用信号量要容易得多
另外,Parallel.ForEach
返回一个ParallelLoopResult
,它使您能够查看循环中的所有操作。要在一组任务中获得同样的可见性,需要做更多的工作。您还可以通过一个方法调用而不是停止多个任务来停止循环。所有线程是否都替换resourceAccountListInfo
?这似乎是错误的区别是:Parallel.ForEach等待所有“照片”完成,然后继续。在Task.Factory.StartNew中,无论照片是否完成,它都会继续运行。@ScottChamberlain抱歉,我只显示了与我的问题相关的部分代码。。现在,在每次迭代中,resourceAccountListInfo上都有额外的处理……最终,由您为您的代码选择您认为合适的最佳解决方案;我想总是很难确定什么是最合适的,所以你需要根据不同的解决方案如何工作来定义它,所以它需要一些尝试和错误,以及性能指标,并且必须检查哪一个是我认为最好的:)我只是想给我的两分钱@johnG有很多方法可以让代码做同样的事情,我不认为你可以概括并说Parallel.ForEach比Task更糟糕。反之亦然,除非在某些情况下……即使在那些情况下,它们也可能有相同的最终结果,所以这没什么关系。当涉及到性能时,这可能很重要。在运行任务管理器时,您应该在任务管理器中查看CPU核心的使用情况,以查看是否使用了所有的CPU可计算性。因此,您使用的是Parallel.ForEach而不是Tas.Factory.StartNew是否正确?使用Parallel.Foreach时的第二个问题在我的例子中,我是否需要显式使用lock来确保没有任何数据损坏,或者这不是必需的?如果我正在处理一个我想并行处理的集合,我会使用Parallel.Foreach
。否则我可能会启动一个任务
。如果并行任务在需要它的东西上运行,比如它们不能同时更新的共享属性,则需要使用某种类型的锁定(或其他管理并发性的方法)。但这种锁定更可能出现在我正在处理的对象中——编写它们以使它们支持并发性——而不是在循环本身中。你说的“否则我可能会启动任务”到底是什么意思??当我需要将锁与Parallel.forEach或与任务一起使用时?您能提供更多详细信息吗?这有点深入。我会从阅读什么时候使用锁开始。它适用于任何多线程。那么,即使我选择执行任务,我也需要使用锁吗?