【问题标题】:WCF callbacks, proxy and thread-safetyWCF 回调、代理和线程安全
【发布时间】:2012-07-04 10:40:11
【问题描述】:

给定一个配置为为每个新客户端创建一个新服务实例的 WCF 双工服务 (NetTcpBinding)(请参阅pattern publish-subscribe),您可以获得每个服务实例的特定回调实例。由于创建了不同的实例,因此可以同时从不同的线程调用属于不同回调的方法。

  • 如果多个线程尝试在同一个回调中调用同一个方法会怎样?
  • 如果他们尝试调用不同的方法但针对相同的回调会发生什么?
  • 我们应该管理从多个线程对这些方法的并发访问吗?在这两种情况下?

现在考虑与服务通信的客户端:为了确保客户端可以使用服务,您必须实例化一个新代理,并且为了调用服务中定义的方法,您必须调用相应的方法代理的。

  • 如果多个线程尝试在同一个代理实例上调用同一个方法会怎样?
  • 如果他们尝试为同一个代理实例调用不同的方法会发生什么?
  • 我们应该管理从多个线程对这些方法的并发访问吗?在这两种情况下?

【问题讨论】:

  • 这不是一个真正的问题。更像是一个整体的领域来学习。您应该只编写大量测试来真正探索事物。让我们面对现实吧,无论如何,没有答案会阻止你这样做。

标签: c# .net multithreading wcf thread-safety


【解决方案1】:

大多数问题的答案取决于您如何管理服务的并发性。没有明确的答案,因为这取决于您为ConcurrencyModeInstanceContextMode 设置的内容。 WCF 的并发管理将使您能够微调服务的线程行为和性能。在concurrency management is available on MSDN 上进行了漫长而艰巨(但非常详细)的阅读。

InstanceContextMode 允许您定义应如何实例化您的服务。对于执行大量繁重工作并处理大量调用的服务,一般的想法是使用 PerCall 实例化,因为此设置每次都会在单独的服务实例上处理传入的客户端请求。

ConcurrencyMode,主要参与者,将允许您定义在给定时间可以访问服务实例的线程数。在ConcurrencyMode=Single 中,一次只有一个线程可以访问服务实例。这还取决于您是否启用了SynchronizationConext,如果SynchronizationConext=true 则如果您的服务正在回答另一个请求,则客户端调用将排队。因此传入的服务调用将排队,直到前面的调用被首先处理。使用ConcurrencyMode=Multiple 设置,允许任意数量的线程访问服务实例,这意味着您的服务可以响应尽可能多的调用,因为线程池中有多少线程(直接与CPU 功率相关)可供它使用。多并发模式的问题是,您的服务在接收和响应调用的顺序上并不那么可靠,因为状态不会被管理,因为SynchronizationContext 默认设置为 false。 concurrency modes and thread safety is available on MSDN 的简短摘要。

这些设置在与InstanceContext 模式结合使用时会影响您的服务性能,请参阅this pretty nice article which explores various concurrency modes and instance context settings and their effects on performance(尽管结果似乎仅在自托管环境中,可能不太代表您将获得的时间在 IIS 中托管时)。

您管理服务并发性的方式将极大地影响其性能。理想情况下,您希望为您的服务提供尽可能多的线程(尝试增加 ThreadPool 的最小线程),并避免传入服务调用排队,只要您的服务有计算资源可供使用。但是过度使用多线程会牺牲状态管理和响应客户端请求的顺序。

【讨论】:

  • 第一个链接不再可用(并且没有来自 archive.org 的结果)。出于这个原因,我总是使用页面或文章的标题作为超链接的文本,最好加上一点引号,这样就有机会再次搜索和找到它。
  • 也许你指的是这个,谁知道呢,没办法知道:Sessions, Instancing, and Concurrency - WCF
猜你喜欢
  • 1970-01-01
  • 2011-08-23
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多