WCF回调,代理和线程安全

enz*_*m83 5 .net c# wcf multithreading thread-safety

给定WCF双工服务(NetTcpBinding)配置为为每个新客户端创建新服务实例(请参阅模式发布 - 订阅),您可以获取每个服务实例的特定回调实例.由于创建了不同的实例,因此可以同时从不同的线程调用属于不同回调的方法.

  • 如果多个线程尝试在同一个回调上调用相同的方法会发生什么?
  • 如果他们尝试调用不同的方法而不是相同的回调会发生什么?
  • 我们应该管理来自多个线程的这些方法的并发访问吗?在这两种情况下?

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

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

Moh*_*and 6

大多数问题的答案取决于您如何管理服务的并发性.没有明确的答案,因为它取决于你为你ConcurrencyMode和你设定的内容InstanceContextMode.WCF的并发管理将使您能够微调服务的线程行为和性能.MSDN上提供了关于并发管理的冗长而艰巨的(但非常详细的)读物.

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

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

当与InstanceContext模式结合使用时,这些设置将影响您的服务性能,请参阅这篇非常好的文章,该文章探讨了各种并发模式和实例上下文设置及其对性能的影响(尽管看起来结果仅在自托管环境中,可能不太代表你在IIS中托管时会得到的时间).

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