在插入 sql 后在 parallel.foreach 循环中清除线程安全集合
Clearing Thread Safe Collections while in parallel.foreach loop after insert to sql
我有一个使用 parallel.foreach 循环的长 运行 过程。在该循环中,我根据传递的内容创建两个不同 类 的实例,执行次要任务,然后添加到线程安全集合。完成后,所有数据都需要插入到 sql。
我遇到的问题是完成的工作量太大,无法在所有处理完成之前保留在集合中。我必须偶尔将保留的内容推送到 SQL,然后从集合中删除推送的内容,以便可以继续进行更多处理而不会 运行 内存不足,我不知道这样做的最佳方法。如果它不是多线程的,我可以很容易地做到这一点,方法是检查集合的数量,如果超过一定数量,调用一个函数,通过批量插入或赋值 [,将内容推送到 SQL =36=] 然后在下一条语句中清除该集合。在 parallel.foreach
内完成此任务的最佳方法是什么?
我愿意使用任何线程安全的集合。到目前为止,我一直在使用 ConcurrentQueue
并考虑切换到 BlockingCollection
,因为我没有看到清除并发队列的方法。我不关心内容的插入顺序,但我确实需要至少能够删除推送到 sql 的内容。
我最好的解决方案是使用 BlockingCollection.GetConsumingEnumerable()
。这样,一旦超过 x 数量,我就可以将该集合的内容复制到另一个线程安全集合,执行我的插入,然后使用该列表使用 BlockingCollection.GetConsumingEnumerable()
从原始列表中删除。完成后,处理临时列表。我只是觉得有更好的方法,因为如果我必须一次迭代一个来删除,这有点违背了多线程的目的。
我见过 pulse and wait 的使用,但我找不到一个看起来安全的好用例。在我测试集合超过一定数量并在将其插入 sql.
之前清除后,我可能会有一些东西通过
我使用的是 4.5 框架,我正在管理两个需要推送但不一定同时推送的不同集合。
我不建议清除并发集合。相反,我会 'replace' 它与一个新线程 - 并处理旧线程的内容,同时其他线程将其内容推送到新线程。
Interlocked.Exchange 是我用来完成此任务的技巧。
我有一个使用 parallel.foreach 循环的长 运行 过程。在该循环中,我根据传递的内容创建两个不同 类 的实例,执行次要任务,然后添加到线程安全集合。完成后,所有数据都需要插入到 sql。
我遇到的问题是完成的工作量太大,无法在所有处理完成之前保留在集合中。我必须偶尔将保留的内容推送到 SQL,然后从集合中删除推送的内容,以便可以继续进行更多处理而不会 运行 内存不足,我不知道这样做的最佳方法。如果它不是多线程的,我可以很容易地做到这一点,方法是检查集合的数量,如果超过一定数量,调用一个函数,通过批量插入或赋值 [,将内容推送到 SQL =36=] 然后在下一条语句中清除该集合。在 parallel.foreach
内完成此任务的最佳方法是什么?
我愿意使用任何线程安全的集合。到目前为止,我一直在使用 ConcurrentQueue
并考虑切换到 BlockingCollection
,因为我没有看到清除并发队列的方法。我不关心内容的插入顺序,但我确实需要至少能够删除推送到 sql 的内容。
我最好的解决方案是使用 BlockingCollection.GetConsumingEnumerable()
。这样,一旦超过 x 数量,我就可以将该集合的内容复制到另一个线程安全集合,执行我的插入,然后使用该列表使用 BlockingCollection.GetConsumingEnumerable()
从原始列表中删除。完成后,处理临时列表。我只是觉得有更好的方法,因为如果我必须一次迭代一个来删除,这有点违背了多线程的目的。
我见过 pulse and wait 的使用,但我找不到一个看起来安全的好用例。在我测试集合超过一定数量并在将其插入 sql.
之前清除后,我可能会有一些东西通过我使用的是 4.5 框架,我正在管理两个需要推送但不一定同时推送的不同集合。
我不建议清除并发集合。相反,我会 'replace' 它与一个新线程 - 并处理旧线程的内容,同时其他线程将其内容推送到新线程。
Interlocked.Exchange 是我用来完成此任务的技巧。