Bor*_*ode 3 semaphore dataflow task task-parallel-library tpl-dataflow
我需要制作可扩展的流程.该进程主要具有I/O操作和一些次要CPU操作(主要是反序列化字符串).该进程在数据库中查询url列表,然后从这些url中获取数据,将下载的数据deserilize到对象,然后将一些数据保存到crm动态以及另一个数据库中.之后我需要更新第一个处理网址的数据库.部分要求是使并行度可配置.
最初我想通过一系列任务实现它,等待并使用Semaphore限制并行性 - 非常简单.然后我读了@Stephen Cleary的一些帖子和答案,建议使用TPL Dataflow,我认为它可能是一个很好的候选人.但是,我想通过使用Dataflow来确保我使代码"复杂化",这是值得的.我也有一个建议使用ForEachAsync扩展方法也很简单,但是我不确定它是否会因为它对集合进行分区而导致内存开销.
TPL Dataflow是否适合这种情况?它如何比Semaphore或ForEachAsync方法更好 - 如果我通过TPL DataFlow在每个其他选项(Semaphore/ForEachASync)上实现它,我将获得什么好处?
该过程主要包含IO操作和一些次要的CPU操作(主要是反序列化字符串).
这几乎就是I/O. 除非这些字符串很大,否则反序列化将不值得并行化.你正在做的那种CPU工作将在噪音中丢失.
因此,您需要关注并发异步.
SemaphoreSlim 正如您所发现的那样,这是标准模式.ForEachAsync可以采取几种形式; 请注意,在您引用的博客文章中,此方法有5种不同的实现,每种实现都是有效的."[T]这里有许多不同的语义可供迭代,每个都会导致不同的设计选择和实现." 出于您的目的(不希望CPU并行化),您不应该考虑使用Task.Run或分区的.在异步并发世界中,任何ForEachAsync实现都只是语法糖,它隐藏了它实现的语义,这就是我倾向于避免它的原因.
这使你SemaphoreSlim对ActionBlock.我通常建议人们从SemaphoreSlim第一个开始,如果他们的需求变得更加复杂(考虑他们将从数据流管道中受益),请考虑转移到TPL Dataflow.
例如,"部分要求是使并行度可配置."
您可以从允许一定程度的并发性开始 - 其中被限制的事物是单个整体操作(从URL获取数据,将下载的数据反序列化为对象,持久保存到crm动态和另一个数据库,并更新第一个数据库).这是SemaphoreSlim一个完美的解决方案.
但是您可能决定要使用多个旋钮:比如说,您下载了多少个url的并发度,以及持久化的单独并发度,以及更新原始数据库的单独程度的并发性.然后你还需要限制这些点之间的"队列":在内存中只有这么多反序列化的对象,等等 - 以确保具有慢速数据库的快速URL不会导致你的应用程序使用过多的问题记忆.如果这些是有用的语义,那么您已经开始从数据流的角度来解决问题,而这就是您可以更好地使用像TPL Dataflow这样的库.
| 归档时间: |
|
| 查看次数: |
402 次 |
| 最近记录: |