【问题标题】:Pass object to thread and get it back after thread has run将对象传递给线程并在线程运行后将其取回
【发布时间】:2011-08-16 14:47:03
【问题描述】:

我会马上说这个。我是线程的业余爱好者。我是一名高级 c# web 开发人员,但我有一个项目需要我填充很多需要很长时间才能填充的对象,因为它们需要 WebRequests要填充的响应。在没有 threading 的情况下,我的一切都可以正常工作,但它的运行速度不足以满足我的要求。我想将所有内容传递给ThreadPool,以便为我管理 threading,因为我可能会同时排队 20,000 个线程,原因很明显。我不想通过一次填充所有请求所需的请求访问网站。

我想做的是传入一个object,填充它,然后将它添加到主thread中的一个collection > 一旦它被填充。然后,一旦填充了所有对象,继续执行程序。在全部填充之前,我不知道需要填充多少对象。

我的问题...最好的方法是什么?

这是我要加速的循环:

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 方法贯穿我传递的指令,告诉它如何填充对象。然后我将它添加到集合中。此外,对象本身可能具有需要此方法运行并填充其数据的属性。

【问题讨论】:

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

标签: c# .net multithreading .net-4.0 threadpool


【解决方案1】:

由于您可能必须等待它们全部完成,因此您只需要Parallel.ForEach() 或等效项即可。和一个线程安全的集合。请注意,对于 I/O 密集型任务,您需要限制线程数。 20.00 线程在任何情况下都是疯狂的。

但我们需要查看更多详细信息(代码)。请注意,没有“主线程中的集合”之类的东西。

【讨论】:

  • 我尝试将我的 foreach 循环更改为使用 Parallel.ForEach,它似乎工作了一点,但我收到一个错误,说它无法更新集合。我假设这是由于 Add 方法试图与另一个线程同时更新集合。有什么方法可以检查锁定情况吗? (我可能没有正确的术语)
  • 是的。我不知道 RunOrdering() 在做什么,但是您必须尽可能地验证每个 Task 是独立的,并在需要共享内容的任何地方使用lock
  • 一切都是独立的,除了添加到集合的调用。我锁定了这个电话,它像梦一样工作。谢谢。
【解决方案2】:

填充大量的对象 需要很长时间才能根据需要进行填充 Web 请求和响应

如果您正在执行请求,请避免使用线程。 两个线程后没有加速,只有两个线程存在。 一大堆空虚。

【讨论】:

  • 我也赞成这个答案,因为它的运行速度似乎并没有快很多,而且实施起来有点痛苦。
【解决方案3】:

几个建议:

如果您使用的是 .net 4,请尝试改用 Tasks。您可以更好地控制日程安排。尽量不共享任何对象,使它们不可变以及所有警告和best practices 关于同步、共享数据等。

其次,您可能想考虑一个进程外解决方案,例如message queues(xMQ 产品或穷人的数据库表作为队列),这样您就有机会在需要时将任务分配到多台机器上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多