2011-05-01 76 views
0

我会马上说出这个问题。我是线程的业余爱好者。我是一个高级c#web开发人员,但我有一个项目,需要我填充很多需要很长时间填充的对象,因为它们需要填充WebRequests响应来填充。我有一切工作没有线程,但它运行速度不够我的要求。我想将所有内容都传递给ThreadPool以便为我管理线程,因为我可能会同时排队20,000个线程,原因很明显。我不想打一个网站,要求一次填充所有请求。将对象传递给线程并在线程运行后将其取回

我想这样做是在对象通过,填充它,然后在主线程添加集合一旦填充。然后,一旦所有对象都被填充,继续执行程序。我不知道有多少物体需要填充,直到它们全部填充。

我的问题...这样做的最佳方法是什么?

这里是我试图加快循环:

foreach (HElement hElement in repeatingTag.RunRepeatingTagInstruction()) 
{ 
    object newObject = Activator.CreateInstance(currentObject.GetType().GetGenericArguments()[0]); 
    List<XElement> ordering = GetOrdering(tagInstructions.Attribute("type").Value); 
    RunOrdering(ordering, newObject, hElement); 
    MethodInfo method = currentObject.GetType().GetMethod("Add"); 
    method.Invoke(currentObject, new[] { newObject }); 
} 

我不知道对象是什么事前,所以我创建一个使用激活它。 RunOrdering方法遍历我传递的指示信息,告诉它如何填充对象。然后我将它添加到集合中。此外,对象本身可能具有需要此方法运行并填充其数据的属性。

+2

如果您的程序的目的是发出20,000个Web请求,那么它并不受限于您将这些任务分配给CPU内核的程度,而是受网络带宽的限制。通过并行执行2-5个请求,你可能会获得很小的加速,但是在这之上并没有太大的改进。您需要的是某种“调度程序”,它保留未完成任务的列表,并始终保持少量并行运行的任务。任务将结果写入共享集合。调度程序在所有任务完成时设置一个信号。 – dtb 2011-05-01 20:53:27

回答

2

由于您可能需要等待它们全部完成,所有您需要的是Parallel.ForEach()或同等产品。和一个线程安全的集合。请注意,对于I/O密集型任务,您希望限制线程的数量。在任何情况下,20.00线程都会疯狂。

但我们需要看到更多细节(代码)。请注意,没有“主线程中的集合”这样的东西。

+1

无论如何,你应该添加代码和其他信息的问题。 – 2011-05-01 21:14:59

+0

我试着改变我的foreach循环来使用Parallel.ForEach,它似乎在工作一点点,但我得到一个错误,说它无法更新集合。我假设这是由于Add方法试图与另一个线程同时更新集合。有没有办法检查锁定情况? (我可能没有这个正确的术语) – light 2011-05-01 21:57:02

+0

是的。我不知道RunOrdering()在做什么,但是你必须尽可能地验证每个Task是否独立,并且在需要共享的地方使用'lock'。 – 2011-05-01 22:03:12

1

填充很多是需要 长的时间来填充,因为它们需要 WebRequests和响应

避免线程,如果你正在做的请求对象。 两个线程之后没有加速,仅存在于两个线程中。 大量的白白浪费。

+0

我也提出了这个答案,因为它似乎没有更快地运行,并且实施起来有点痛苦。 – light 2011-05-01 22:51:02

+0

我知道,已经在那里,也有同样的失望:/ – 2011-05-02 00:20:19

0

夫妇的建议:

如果您使用Tasks而不是.NET 4的尝试。你可以更好地控制调度。尽量不共享任何对象,使他们不变的,所有的警告和best practices关于同步,共享数据等

其次,你可能要考虑一个彻头彻尾的流程解决方案一样message queues的(XMQ产品或穷人的数据库表作为队列),所以如果需要的话,你将有机会将任务分配到多台机器上。

相关问题