TPL 数据流与普通信号量

2024-01-27

我需要制定一个可扩展的流程。该进程主要有 I/O 操作和一些次要的 CPU 操作(主要是反序列化字符串)。该流程在数据库中查询 url 列表,然后从这些 url 中获取数据,将下载的数据反序列化为对象,然后将部分数据保存到 crm 动态以及另一个数据库中。之后我需要更新第一个处理 url 的数据库。部分要求是使并行度可配置。

最初,我想通过一系列带有等待的任务来实现它,并使用信号量限制并行性 - 非常简单。然后我读了 @Stephen Cleary 的一些帖子和答案,其中建议使用 TPL Dataflow,我认为它可能是一个很好的候选者。然而,我想确保我通过使用数据流来“复杂化”代码是为了一个有价值的事业。我还得到了使用的建议ForEachAsync 扩展方法 https://blogs.msdn.microsoft.com/pfxteam/2012/03/05/implementing-a-simple-foreachasync-part-2/这也很容易使用,但是我不确定它是否会因为它对集合进行分区的方式而导致内存开销。

对于这种情况,TPL Dataflow 是一个不错的选择吗?它比 Semaphore 或 ForEachAsync 方法更好 - 如果我通过 TPL DataFlow 实现它而不是其他每个选项(Semaphore/ForEachASync),我实际上会获得什么好处?


该进程主要有IO操作和一些次要的CPU操作(主要是反序列化字符串)。

这几乎只是 I/O。除非那些字符串是huge,反序列化不值得并行化。您正在执行的 CPU 工作类型将被淹没在噪音中。

因此,您需要关注并发异步。

  • SemaphoreSlim正如您所发现的,这是标准模式。
  • TPL Dataflow 还可以实现并发(异步和并行形式)。

ForEachAsync可以采取多种形式;请注意,在博客文章 https://blogs.msdn.microsoft.com/pfxteam/2012/03/05/implementing-a-simple-foreachasync-part-2/你提到的,有5该方法有不同的实现,每种实现都是有效的。 “迭代可能有许多不同的语义,每种语义都会导致不同的设计选择和实现。”出于您的目的(不希望 CPU 并行化),您不应该考虑使用Task.Run或分区。在异步并发世界中,任何ForEachAsync实现只是隐藏它实现的语义的语法糖,这就是我倾向于避免它的原因。

这给你留下了SemaphoreSlim vs. ActionBlock。我通常建议人们从SemaphoreSlim首先,如果他们的需求变得更加复杂(他们似乎会从数据流管道中受益),请考虑转向 TPL 数据流。

例如,“部分要求是使并行度可配置。”

您可以从允许一定程度的并发开始 - 被限制的事物是单个整体操作(从 url 获取数据、将下载的数据反序列化为对象、持久保存到 crm 动态和另一个数据库中,以及更新第一个数据库)。这是哪里SemaphoreSlim将是一个完美的解决方案。

但是您可能决定要拥有多个旋钮:例如,一个用于下载 URL 数量的并发度,一个用于持久化的单独并发度,以及一个用于更新原始数据库的单独并发度。然后,您还需要限制这些点之间的“队列”:内存中只有这么多反序列化对象等 - 以确保具有慢速数据库的快速 url 不会导致您的应用程序使用过多的问题记忆。如果这些是有用的语义,那么您已经开始从数据流的角度来处理问题,这就是您可能会更好地使用像 TPL Dataflow 这样的库的服务。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TPL 数据流与普通信号量 的相关文章

  • 实体框架:ObjectSet 及其(泛型)方差

    我使用 EntityFramework POCO 事情是这样的 public interface IBaseType int Id get set public class BaseType IBaseType public virtual
  • Monitor.TryEnter(object) 和 Monitor.TryEnter(object, ref bool) 之间存在什么重要区别?

    这些代码片段的行为似乎应该相同 1 Monitor TryEnter 对象 if Monitor TryEnter lockObject try DoSomething finally Monitor Exit lockObject 2 M
  • SQL Server批量上传策略

    我使用以下函数将数据从 CSV 上传到 SQL 表 有更好的方法吗 我现在担心连接长时间保持 因此需要减少 public bool SaveProxyBulkUploadData List
  • 堆内存问题

    有一个 WCF 自托管服务必须在 99 的时间内正常工作 有时我们会遇到这样的记忆问题 但问题发生后 服务一切正常 我们该如何处理这个问题 任何关于提供能够在不同情况下生存的强大服务的提示和要点都非常受欢迎 我不太确定问题出在哪里 但内存泄
  • ODP.NET 可以重新分发吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Oracle ODP NET 库是否可重新分发 例如 我是否可以简单地将 Oracle DataAccess dll 包含在我的应用程序中
  • C# 组件事件?

    我正在尝试编写一个将公开事件的 C 组件 该组件将由非托管 C 应用程序导入 根据一些教程 我想出了这段代码 针对 C 端 namespace COMTest ComVisible true Guid 02271CDF BDB9 4cfe
  • String.Format - 它如何工作以及如何实现自定义格式字符串

    With String Format 例如可以格式化DateTime对象以许多不同的方式 每次我寻找所需的格式时 我都需要在互联网上搜索 我几乎总能找到一个可以使用的例子 例如 String Format 0 MM dd yyyy Date
  • 如何将当前用户信息传递到 DDD 中的所有层

    类似的问题以前曾被问过 但不完全相同 除非我错过了 我想通过我的服务 域 域事件 域事件处理程序传递 IUserInfo 类实例 什么是最好的方法 我是不是该 通过注册使用 IoC 注入它 针对 Httpcontext Current se
  • 如何使 sgen.exe 保留程序集的版本?

    我想为我的程序集创建一个序列化程序集 sgen做得很好 但我不知道如何让它为序列化程序集分配与源程序集相同的版本 有任何想法吗 sgen似乎默认采用源程序集版本 这是相当合理的 这是我的运行方式 没有什么特别的 PathToSDK Micr
  • 对象 xml 反序列化问题?

    我的对象具有父子关系 每个子对象都有一个Parent指向其容器的属性 当这个对象在应用程序中创建时 它就被设置了 因此没有问题 此 Parent 属性标记有 XmlIgnore 属性 因为它需要设置为其运行时父实例 那么 在对象反序列化后初
  • 运行 C# exe 文件

    复制 为什么我的 NET 应用程序在从网络驱动器运行时会崩溃 https stackoverflow com questions 148879 why does my net application crash when run from
  • 调试WCF时无法自动单步进入服务器

    我得到了可怕的 无法自动进入服务器 无法调试远程过程 这通常表明服务器上尚未启用调试 现在 我一直在读我需要添加
  • 西班牙语单词的正则表达式是什么?

    正则表达式语言使用 B 来包含 A Z a z 0 9 和 并且 b 被定义为单词边界 如何编写匹配所有有效西班牙语单词 包括诸如 等字符 的正则表达式 我正在使用 NET 使用西班牙语区域设置并使您的正则表达式区域设置敏感
  • 如何将外部程序集的类型添加到工具箱控件? (WPF)

    我正在尝试在我的 WPF 应用程序中执行类似的操作 ToolboxControl ctrl new ToolboxControl Assembly assembly Assembly LoadFile file var category n
  • 使用 C# .NET 从操纵杆获取输入

    我在谷歌上搜索了这个 但我想到的唯一的东西已经过时并且不起作用 有人知道如何使用 C NET 获取操纵杆数据吗 由于这是我在研究 C 中的操纵杆 游戏手柄输入时在 google 上获得的最高点击次数 因此我认为我应该发布一个回复供其他人查看
  • 在 foreach 循环中启动一个新线程

    我有一个对象列表 我想循环该列表并启动一个新线程 传入当前对象 我写了一个我认为应该这样做的例子 但它不起作用 具体来说 线程似乎在每次迭代中都被覆盖 但这对我来说并没有什么意义 因为我每次都会创建一个新的 Thread 对象 这是我写的测
  • 如何在公共交通中记录失败的消息?

    我正在寻找一个好的解决方案来在超出重试限制后立即记录失败消息 而无需处理错误队列 到目前为止我发现了什么 我可以继承InMemory入站消息跟踪器并覆盖是否超出重试限制 但此时除了 id 之外 没有关于消息本身的信息 我可以实施IInbou
  • 通过 TCP/.NET SSLStream 发送文件很慢/无法正常工作

    我正在编写一个与 SSL 配合使用的服务器 客户端应用程序 通过SSLStream 它必须做很多事情 不仅仅是文件接收 发送 目前 它的工作原理是 只有一个连接 我总是使用从客户端 服务器发送数据SSLStream WriteLine 并使
  • .NET:EventHandler 竞争条件修复如何工作?

    以下模式用于在引发事件时避免竞争条件 以防另一个线程取消订阅 MyEvent 使其为空 class MyClass public event EventHandler MyEvent public void F EventHandler h
  • 从 DataGridColumn 中绑定到 DataContext 属性

    财产Foo在我的DataContext ViewModel Visibility Foo 但我不知道如何访问Foo里面一个Column 在这种情况下 我认为它可能正在寻找Foo在任何绑定到的对象中DataGrid ItemsSource

随机推荐