WCF 服务和线程
Posted
技术标签:
【中文标题】WCF 服务和线程【英文标题】:WCF Service and Threading 【发布时间】:2011-04-27 12:39:20 【问题描述】:我创建了一个简单的 WCF (.NET 3.5) 服务,它定义了 10 个合同,这些合同基本上是对所提供数据的计算。目前,我预计很少有客户会致电其中一些合同。如何使服务响应更快?我有一种感觉,服务会等到它处理一个请求才能转到下一个请求。 如何在 WCF 中使用多线程来加快速度?
【问题讨论】:
当我说您的反应缓慢时,我理解您的意思吗?客户每分钟打多少电话。什么是慢? 【参考方案1】:虽然我同意 Justin's answer,但我相信这里可以进一步阐明 WCF 的工作原理。
您做出具体声明:
我感觉服务会 等到它处理一个请求 去下一个。我该如何使用 WCF 中的多线程以加快速度 起来了吗?
服务的并发性(它可以同时进行多少调用)取决于附加到服务的ConcurrencyMode
value for the ServiceBehavior
。默认情况下,这个值为ConcurrencyMode.Single
,意思是会一个接一个的序列化调用。
但是,这可能不像您想象的那么严重。如果您的服务的InstanceContextMode
等于InstanceContextMode.PerCall
,那么这不是问题;每次调用都会创建一个新的服务实例,不会用于任何其他调用。
但是,如果您有一个单例或基于会话的服务对象,那么对该服务实现实例的调用将被序列化。
您始终可以更改ConcurrencyMode
,但请注意,如果您这样做,您将不得不手动处理并发问题并访问您的资源,因为您已明确告诉 WCF 您将这样做。
重要的是不要仅仅因为您认为它会提高性能而改变这些。虽然对于并发性而言并不多,但服务的实例化方面在很大程度上是服务身份的一部分(如果它是基于会话的或不是基于会话的)并且更改它们会影响使用服务的客户端,所以不要这样做轻轻一点。
当然,这与实际实现服务的代码是否高效无关。当您指出是这种情况时,这绝对是需要调查的事情。
【讨论】:
【参考方案2】:这绝对是未成熟的优化。先实现你的服务,看看有没有问题。
我想你会发现你什么都不担心。当请求处理时,服务器不会阻止单个请求。 IIS/WCF 应该按原样很好地为您处理事情。
【讨论】:
【参考方案3】:我不熟悉 WCF,但是这个过程可以异步吗?
如果您期待大量数据和密集计算,一种选择可能是发送id
,在单独的线程中计算值,然后提供使用初始id
返回结果的方法。
类似:
int id = Service.CalculateX(...);
...
var y = Service.GetResultX(id);
【讨论】:
【参考方案4】:默认情况下,实例化是PerSession
。
见WCF Service defaults
但是,如果您使用不支持会话的会话绑定(如 BasicHttpBinding)或通道/客户端未创建会话,则其行为类似于 PerCall
请参阅 [绑定类型会话支持] (https://docs.microsoft.com/en-us/dotnet/framework/wcf/system-provided-bindings)。
每个 WCF 客户端对象都将创建一个 Session,并且对于每个会话,都会有一个服务器实例,该服务器实例具有一个线程,该线程同步地为来自该特定 WCF 客户端对象的所有调用提供服务。
因此,多个客户端将各自拥有自己的会话,因此默认情况下服务器实例和线程不会相互阻塞。 它们只会在数据库、CPU 等共享资源上相互影响。
见Using sessions
像其他人建议的那样,在开始使用实例化和并发模式之前,您应该确保实现高效。
如果没有真正的理由调用服务器,您也可以考虑客户端计算。
【讨论】:
以上是关于WCF 服务和线程的主要内容,如果未能解决你的问题,请参考以下文章