我创建了一个简单的WCF (.NET 3.5)服务,定义了10个合同,基本上是对提供的数据进行计算。目前我预计很少的客户端会调用其中一些合同。如何使服务更加响应?我有一种感觉,服务会等待处理一个请求才能继续下一个请求。
我该如何在WCF中使用多线程来加速处理?
我创建了一个简单的WCF (.NET 3.5)服务,定义了10个合同,基本上是对提供的数据进行计算。目前我预计很少的客户端会调用其中一些合同。如何使服务更加响应?我有一种感觉,服务会等待处理一个请求才能继续下一个请求。
我该如何在WCF中使用多线程来加速处理?
尽管我同意Justin的答案,但我认为在这里可以更详细地介绍WCF的工作原理。
您提出了一个具体的声明:
我有一种感觉,该服务将等待处理一个请求后再进行下一个请求。如何在WCF中使用多线程来加速处理速度?
服务的并发性(它可以同时处理多少个调用)取决于附加到服务的ServiceBehavior
的ConcurrencyMode
值。默认情况下,此值为ConcurrencyMode.Single
,这意味着它将一个接一个地序列化调用。
然而,这可能不是您想象中的那么严重。如果您的服务的InstanceContextMode
等于InstanceContextMode.PerCall
,那么这就不是问题;每次调用都会创建服务的新实例,并且不会用于任何其他调用。
但是,如果您有一个单例或基于会话的服务对象,则对该服务实现的调用将被序列化。
您始终可以更改ConcurrencyMode
,但请注意,如果这样做,您将必须手动处理并发问题和访问您的资源,因为您已明确告诉WCF您将这样做。
重要的是不要仅仅因为你认为它会提高性能就改变这些内容。尽管对于并发来说不是很重要,但服务的实例化方面非常重要,它是服务身份的一部分(无论它是基于会话还是非会话),更改它们会影响使用服务的客户端,所以不要轻率地去做。
当然,这并不意味着实际实现服务的代码是否有效率。当你指出这种情况时,绝对需要进行调查。
这绝对是过早的优化。先实现你的服务,看看是否存在问题。
我认为你会发现你在担心无用的事情。服务器不会在单个请求处理时阻塞。IIS/WCF应该已经很好地处理了这些情况。
我不熟悉WCF,但这个过程可以是异步的吗?
如果您期望处理大量数据和密集计算,一个选项是发送一个id
,在单独的线程中计算值,然后提供一种方法使用初始id
返回结果。
类似于:
int id = Service.CalculateX(...);
...
var y = Service.GetResultX(id);
默认情况下,实例化是PerSession
。
请参见WCF服务默认值
但是,如果您使用不支持会话的会话绑定(如BasicHttpBinding),或者通道/客户端不创建会话,则此行为类似于PerCall
请参见[绑定类型会话支持](https://learn.microsoft.com/en-us/dotnet/framework/wcf/system-provided-bindings)。
每个WCF客户端对象都将创建一个会话,对于每个会话,都将有一个服务器实例,该实例具有单个线程,同步地处理来自该特定WCF客户端对象的所有调用。
因此,默认情况下,多个客户端将分别拥有自己的会话和服务器实例以及线程,并且不会相互阻塞。 它们只会在共享资源(如DB、CPU等)上相互影响。
请参见使用会话
像其他人建议的那样,在开始尝试实例化和并发模式之前,应该确保实现是高效的。
如果没有实际理由调用服务器,则还可以考虑客户端计算。