WCF服务和线程处理

9

我创建了一个简单的WCF (.NET 3.5)服务,定义了10个合同,基本上是对提供的数据进行计算。目前我预计很少的客户端会调用其中一些合同。如何使服务更加响应?我有一种感觉,服务会等待处理一个请求才能继续下一个请求。

我该如何在WCF中使用多线程来加速处理?


当我说你遇到了缓慢的响应时,我理解得没错吧?一个客户每分钟打多少个电话?什么是缓慢? - Ralf de Kleine
4个回答

22

尽管我同意Justin的答案,但我认为在这里可以更详细地介绍WCF的工作原理。

您提出了一个具体的声明:

我有一种感觉,该服务将等待处理一个请求后再进行下一个请求。如何在WCF中使用多线程来加速处理速度?

服务的并发性(它可以同时处理多少个调用)取决于附加到服务的ServiceBehaviorConcurrencyMode。默认情况下,此值为ConcurrencyMode.Single,这意味着它将一个接一个地序列化调用。

然而,这可能不是您想象中的那么严重。如果您的服务的InstanceContextMode等于InstanceContextMode.PerCall,那么这就不是问题;每次调用都会创建服务的新实例,并且不会用于任何其他调用。

但是,如果您有一个单例或基于会话的服务对象,则对该服务实现的调用将被序列化。

您始终可以更改ConcurrencyMode,但请注意,如果这样做,您将必须手动处理并发问题和访问您的资源,因为您已明确告诉WCF您将这样做。

重要的是不要仅仅因为你认为它会提高性能就改变这些内容。尽管对于并发来说不是很重要,但服务的实例化方面非常重要,它是服务身份的一部分(无论它是基于会话还是非会话),更改它们会影响使用服务的客户端,所以不要轻率地去做。

当然,这并不意味着实际实现服务的代码是否有效率。当你指出这种情况时,绝对需要进行调查。


4

这绝对是过早的优化。先实现你的服务,看看是否存在问题。

我认为你会发现你在担心无用的事情。服务器不会在单个请求处理时阻塞。IIS/WCF应该已经很好地处理了这些情况。


1

我不熟悉WCF,但这个过程可以是异步的吗? 如果您期望处理大量数据和密集计算,一个选项是发送一个id,在单独的线程中计算值,然后提供一种方法使用初始id返回结果。

类似于:

 int id = Service.CalculateX(...);
 ...
 var y = Service.GetResultX(id);

0

默认情况下,实例化是PerSession。 请参见WCF服务默认值

但是,如果您使用不支持会话的会话绑定(如BasicHttpBinding),或者通道/客户端不创建会话,则此行为类似于PerCall

请参见[绑定类型会话支持](https://learn.microsoft.com/en-us/dotnet/framework/wcf/system-provided-bindings)。

每个WCF客户端对象都将创建一个会话,对于每个会话,都将有一个服务器实例,该实例具有单个线程,同步地处理来自该特定WCF客户端对象的所有调用。

因此,默认情况下,多个客户端将分别拥有自己的会话和服务器实例以及线程,并且不会相互阻塞。 它们只会在共享资源(如DB、CPU等)上相互影响。

请参见使用会话

像其他人建议的那样,在开始尝试实例化和并发模式之前,应该确保实现是高效的。

如果没有实际理由调用服务器,则还可以考虑客户端计算。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接