在插入 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 是我用来完成此任务的技巧。