【问题标题】:can a long running for loop be broken into multiple thread slices in c#可以在c#中将长时间运行的for循环分成多个线程片吗
【发布时间】:2009-07-16 21:09:38
【问题描述】:

我有一个需要很长时间才能执行的 For 循环,我正在循环中创建一个新行并将其添加到数据表中。

我想要的是在多个线程上处理这个长时间运行的进程。例如:- 2000 行在一个线程上有一个 for 循环,在另一个线程上有另外 2000 行等等。

请提供一些源代码以在 c# 中实现此目的。

【问题讨论】:

  • 除非您发布代码,否则您将无法获得明确的答案。并行化代码(通常)是不平凡的,数据之间的微妙交互可以使其几乎不可能获得有意义的加速。做错了,你甚至可以让你的代码变慢或产生不正确的输出。

标签: c# multithreading


【解决方案1】:

我不太确定为什么每个人似乎都不赞成你这样做。在很多情况下,通过使用多线程可以大大加快诸如此类的进程。不过需要考虑的一些事项:

现在是什么减慢了这个过程? CPU 是否是瓶颈,并且某些内核未被使用?如果是这样,那么进行并行处理可能是一个很好的目标,如果是磁盘、网络或内存,那么您将不会从跨线程拆分它获得任何好处。

顺序重要吗?确保事情以特定顺序完成在多线程场景中可能会很痛苦。如果您需要结果以与 for 循环运行相同的顺序返回,那么您可能需要想办法在 一切完成后对它们进行排序。通过额外的处理,您可能不会获得任何收益。

有共享资源吗?多个线程会试图访问同一个对象吗?更重要的是,他们会尝试编辑它(例如计数器)吗?在这种情况下,您需要使用锁,而等待访问所花费的所有时间可能会使多线程解决方案比单线程解决方案慢(或至少阻塞更多 CPU 资源)。

考虑到所有这些注意事项,您可能会从良好的并行实现中发现巨大的好处。有一些库可以为您提供 foreach 循环的多线程版本,而您的工作量很少。例如有一个微软版本here。

【讨论】:

    【解决方案2】:

    这实际上取决于您的代码在循环中执行的操作。循环的每次迭代都是embarrassingly parallel workload 吗?如果没有看到代码,就不可能知道你想做的事情是否可行,因为不是每个循环都是可并行的。

    【讨论】:

      【解决方案3】:

      将按顺序发生的动作(例如循环)生成到单独的线程是不明智的。

      您不会获得性能提升。显然你有某种瓶颈(数据库,如果我理解正确的话),并且在那个不会上产生几个线程来提高性能。它甚至会恶化它。

      【讨论】:

      • 不涉及数据库交互。只涉及一点字符串操作。
      【解决方案4】:

      时间都花在了哪里?如果插入到数据库中,那么更努力地敲击数据库可能会使这个过程变慢!

      【讨论】:

      • 迭代需要时间。有数百万条记录我必须逐行读取并进行一些操作。我在 for 循环结束后使用 sqlbulkcopy 插入数据库。插入大约需要一分钟,但操作需要 10 分钟。
      【解决方案5】:

      分析延迟的实际来源很重要...我怀疑它不是您的程序的速度,而是它需要时间的数据库...多线程在这里无济于事

      【讨论】:

        【解决方案6】:

        我不确定你是否会从在多个线程上拆分你的操作中受益:你有一个共享资源,它对于写操作不是线程安全的(DataTable.Rows.Add 确实是一个写操作)。

        如果每个数据行的创建时间很长,您可以拆分创建 DataRow 对象,将它们推入缓冲区,然后再将它们添加到DataTable。

        【讨论】:

          猜你喜欢
          • 2015-11-14
          • 2010-12-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-15
          • 1970-01-01
          相关资源
          最近更新 更多