【问题标题】:Best technique to thread a web service call线程 Web 服务调用的最佳技术
【发布时间】:2015-10-12 17:55:26
【问题描述】:

我有一个网站需要调用网络服务 1 到 10,000 次。目前这是在 foreach 循环中完成的,如下所示:

List<Address> addresses
List<Response> responses = new List<Response>();
foreach(Address address in addresses){
  //Setup web service call
  //Call web service
  //Parse response into object for front end
  responses.Add(CustomReponseObject)
}
// The responses object is then just serialized and set to the front end client to parse through.

当前的方法不是线程化的,我想加快它的速度。不确定我应该使用托管线程还是使用新的 Async Await 关键字。

我开始了这个过程,然后挂断了新的 Async 关键字是否可以工作,使用响应列表上的锁定,或者是否可能需要类似 ConcurrentBag 的东西?我已经阅读了所有三个选项,但不确定哪个选项最适合我的用例?

【问题讨论】:

  • 您能否举例说明async 如何替代ConcurrentBag? (请注意,通常“最佳方法”问题是基于意见/过于宽泛而没有具体目标。您的帖子中目前没有任何内容表明您当前的方法不可接受的原因)

标签: c# multithreading collections


【解决方案1】:

您应该使用 async/await,因为它会在等待 IO 操作调用 Web 服务完成时最大限度地减少托管线程的使用。

full example on MSDN 显示了这个确切的模式。

对于容器,如果您坚持使用List&lt;T&gt;,则必须在通过锁添加时控制对列表的访问,因为该类在修改时不是线程安全的(多个线程可以同时读取)。

更好的选择是ConcurrentQueue&lt;T&gt;,因为它针对这种读/写模式进行了优化(感谢@Scott 的观察)。

【讨论】:

  • 您真的是指在列表对象本身上加锁吗?我喜欢一个单独的、私有的锁定对象。
  • @RobertHarvey:不,我也总是使用私有锁定对象。我会在我的回答中更清楚地说明这一点。
  • 关于ConcurrentBag&lt;T&gt; 的另一点,它针对同一线程同时插入和拉出包的情况进行了优化(例如,许多线程正在获取和返回项目的对象池到池),这被称为“混合生产者 - 消费者场景”。对于“纯生产者-消费者场景”,线程要么从集合中添加或删除,但ConcurrentQueue&lt;T&gt; 并非两者都具有更好的性能。有关详细信息,请参阅 MSDN 文章“When to Use a Thread-Safe Collection”。
  • 谢谢斯科特,我没有考虑过的好观察。我正在根据这个和我刚刚观察到的另一个不准确之处更新我的答案。
  • 我的用例是容器在被遍历之前已经完全加载,所以 ConcurrentQueue 在 ConcurrentBag 上是有意义的,但是 ConcurrentQueue 与锁定列表呢?
猜你喜欢
  • 2010-10-31
  • 2011-12-23
  • 2013-07-27
  • 1970-01-01
  • 2017-05-24
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
  • 1970-01-01
相关资源
最近更新 更多