C# 最大限度地利用Parallel.For或Parallel.Foreach循环
在我的小型控制台应用程序中,我有一个嵌套的Parallel.For和PLINQ语句结构,基本上执行网络绑定操作(执行http请求),如下所示:C# 最大限度地利用Parallel.For或Parallel.Foreach循环,c#,multithreading,performance,parallel-processing,parallel.foreach,C#,Multithreading,Performance,Parallel Processing,Parallel.foreach,在我的小型控制台应用程序中,我有一个嵌套的Parallel.For和PLINQ语句结构,基本上执行网络绑定操作(执行http请求),如下所示: Parallel.For(0,users.count(), index=>{ // here I try to perform HTTP requests for multiple users }); Parallel.For(0,users.count(), index=>{ // Some stuff is done before
Parallel.For(0,users.count(), index=>{
// here I try to perform HTTP requests for multiple users
});
Parallel.For(0,users.count(), index=>{
// Some stuff is done before the PLINQ statement is called...
newFilteredList.AsParallel().WithDegreeOfParallelism(60).ForAll(qqmethod =>
{
var xdocic = new XmlDocument();
xdocic.LoadXml(SendXMLRequestToEbay(null, null, qqmethod.ItemID, true, TotalDaysSinceLastUpdate.ToString(), null));
int TotalPages = 0;
if (xdocic.GetElementsByTagName("TotalNumberOfPages").Item(0) != null)
{
TotalPages = Convert.ToInt32(xdocic.GetElementsByTagName("TotalNumberOfPages").Item(0).InnerText);
}
if (TotalPages > 1)
{
for (int i = 1; i < TotalPages + 1; i++)
{
Products.Add(SendXMLRequestToEbay(null, null, qqmethod.ItemID, false, TotalDaysSinceLastUpdate.ToString(), i.ToString()));
}
}
else
{
Products.Add(SendXMLRequestToEbay(null, null, qqmethod.ItemID, false, TotalDaysSinceLastUpdate.ToString(), "1"));
}
});
});
从DB中填写用户列表,然后我执行以下操作:
Parallel.For(0,users.count(), index=>{
// here I try to perform HTTP requests for multiple users
});
Parallel.For(0,users.count(), index=>{
// Some stuff is done before the PLINQ statement is called...
newFilteredList.AsParallel().WithDegreeOfParallelism(60).ForAll(qqmethod =>
{
var xdocic = new XmlDocument();
xdocic.LoadXml(SendXMLRequestToEbay(null, null, qqmethod.ItemID, true, TotalDaysSinceLastUpdate.ToString(), null));
int TotalPages = 0;
if (xdocic.GetElementsByTagName("TotalNumberOfPages").Item(0) != null)
{
TotalPages = Convert.ToInt32(xdocic.GetElementsByTagName("TotalNumberOfPages").Item(0).InnerText);
}
if (TotalPages > 1)
{
for (int i = 1; i < TotalPages + 1; i++)
{
Products.Add(SendXMLRequestToEbay(null, null, qqmethod.ItemID, false, TotalDaysSinceLastUpdate.ToString(), i.ToString()));
}
}
else
{
Products.Add(SendXMLRequestToEbay(null, null, qqmethod.ItemID, false, TotalDaysSinceLastUpdate.ToString(), "1"));
}
});
});
然后在这个for循环中,我执行一个plinq语句,通过HTTP请求获取这个用户的信息
现在我总共得到两个嵌套循环,如下所示:
Parallel.For(0,users.count(), index=>{
// here I try to perform HTTP requests for multiple users
});
Parallel.For(0,users.count(), index=>{
// Some stuff is done before the PLINQ statement is called...
newFilteredList.AsParallel().WithDegreeOfParallelism(60).ForAll(qqmethod =>
{
var xdocic = new XmlDocument();
xdocic.LoadXml(SendXMLRequestToEbay(null, null, qqmethod.ItemID, true, TotalDaysSinceLastUpdate.ToString(), null));
int TotalPages = 0;
if (xdocic.GetElementsByTagName("TotalNumberOfPages").Item(0) != null)
{
TotalPages = Convert.ToInt32(xdocic.GetElementsByTagName("TotalNumberOfPages").Item(0).InnerText);
}
if (TotalPages > 1)
{
for (int i = 1; i < TotalPages + 1; i++)
{
Products.Add(SendXMLRequestToEbay(null, null, qqmethod.ItemID, false, TotalDaysSinceLastUpdate.ToString(), i.ToString()));
}
}
else
{
Products.Add(SendXMLRequestToEbay(null, null, qqmethod.ItemID, false, TotalDaysSinceLastUpdate.ToString(), "1"));
}
});
});
Parallel.For(0,users.count(),index=>{
//在PLINQ语句被调用之前做了一些事情。。。
newFilteredList.AsParallel()。具有DegreeOfParallelism(60).ForAll(qqmethod=>
{
var xdocic=new XmlDocument();
LoadXml(SendXMLRequestToEbay(null,null,qqmethod.ItemID,true,TotalDaysSinceLastUpdate.ToString(),null));
int TotalPages=0;
if(xdoc.GetElementsByTagName(“TotalNumberOfPages”).Item(0)!=null)
{
TotalPages=Convert.ToInt32(xdoc.GetElementsByTagName(“TotalNumberOfPages”).Item(0.InnerText);
}
如果(总页数>1)
{
对于(int i=1;i
我试着像使用常规的for循环一样使用外部for循环,我注意到它的运行速度比这样快得多,也比这样好得多
这里最让我担心的是,我在运行控制台应用程序时检查CPU的利用率,它总是接近总CPU功率的0.5-3%
因此,我尝试执行HTTP请求的方式如下:
一次15个用户*这15个用户的HTTP请求量
我做错了什么?并行类不适用于非CPU限制的工作。HTTP请求是I/O绑定的。另外,
产品的类型是什么
,如果它只是一个列表
,那么该类不是线程安全的,并且您在同时使用多个线程写入时正在破坏该类。@ScottChamberlain您建议我用什么替换第一个外部for循环?我希望能够为这些用户处理15个并同时发送15个http请求,我该怎么做?@ScottChamberlain产品是并发包=)相反,您可以在一个链中有两个块,一个用于发送请求,一个用于处理,您可以为每个块设置最大并行度。请参阅,它有两个块,一个并行获取记录,然后一个一次处理一个记录,将其添加到列表中。您可以将第二个块转换为所需的“处理”,并将其设置为比1更高的并行度。