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 服务和线程的主要内容,如果未能解决你的问题,请参考以下文章

与命名管道和 WCF 服务的进程间通信:线程问题

单例模式的多线程 WCF

WCF 主机程序是不是为该服务打开了第二个线程?

为啥 WCF 服务能够处理来自不同进程的调用而不是来自线程的调用

如何在多线程或基于 wcf 服务的应用程序中正确使用事件?

在具有 2 个不同 .SVC 文件的多线程环境中调用 WCF 服务。同时调用两个服务时出错