WCF服务是否使用多个线程来处理传入的请求?

时间:2012-02-17 05:37:33

标签: c# .net multithreading wcf threadpool

如何确保WCF服务使用ThreadPool中的线程来处理传入的消息?

目前简单的方法调用,如'return null;'在处理其他请求时需要大约45秒

以下是我如何注释我的服务类:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
    public partial class MyService : IMyService {
...
}

但是当我在任务管理器中观察进程时,它似乎使用了一定数量的线程。即使在负载下也是如此。


public ActionResult SelectDatabase(string param)
        {
            if (!String.IsNullOrEmpty(param))
            {
            try
            {
                MyServicece svc = new MyService();
                Database[] dbsArray = svc.GetDatabases(param);
                if (depsArray != null)
                    ViewData["depsArray"] = depsArray;

                return View();
            }
            catch (Exception exc)
            {
                // log here                
                return ActionUnavailable();
            }
        }

这是我的服务行为:

<?xml version="1.0"?>
<configuration>
  <runtime>

  </runtime>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="100" />
    </connectionManagement>
  </system.net>
  <system.serviceModel>
    <diagnostics performanceCounters="Default" />
    <bindings>      
      <netTcpBinding>
        <binding sendTimeout="00:02:00" receiveTimeout="00:02:00" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
          <security mode="None">           
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <behaviors>
      <endpointBehaviors>
        <behavior name="CrossDomainServiceBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="MyService.MyServiceBehavior">
          <serviceThrottling maxConcurrentCalls="100"   maxConcurrentInstances="100" maxConcurrentSessions="100" />
          <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="MyService.MyServiceBehavior" name="MyService.MyService">
        <endpoint address="MyService" binding="netTcpBinding" contract="AService.IAServ"  isSystemEndpoint="false" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
      <service behaviorConfiguration="MyService.MyServiceBehavior" name="MyService.MyServiceAdmin">
        <endpoint address="MyServiceAdmin" binding="netTcpBinding" contract="MyService.IMyServiceAdmin"  isSystemEndpoint="false" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />        
      </service>
    </services>
  </system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

以下是我创建服务实例的方法:

ServiceHost myserviceHost = new ServiceHost(typeof(MyService), new Uri(String.Format("net.tcp://{0}/", _bindAddress)));
            myserviceHost.Open();
            Console.WriteLine(myserviceHost.BaseAddresses[0]);

1 个答案:

答案 0 :(得分:5)

InstanceContextMode和ConcurrencyMode是单独的概念,但它们之间有一定程度的相互作用 - I blogged about this一段时间内

在IO线程池线程上处理WCF调用。假设您没有执行类似ConcurrencyMode.SingleInstanceContextMode.Single的操作,它将序列化每次调用服务,线程池管理器将尝试平衡线程数与工作速率。

如果5个线程可以处理并发请求的数量,那么它将使用多少个。您可能会看到线程池可以跟上您可以看到的线程数的工作速度。您可以非常高兴地使用比核心更多的线程,因为只要线程不是纯粹的CPU绑定,操作系统就可以通过在先前运行的线程启动IO时将线程切换到CPU来获得吞吐量。如果CPU完全最大化,那么线程池管理器的启发式将使它更加谨慎地将更多线程添加到线程池中

然而,还有另外两个潜在的问题:

  1. 基于会话的绑定可以在客户端阻止,同时通过同一代理存在多个并发出站请求。你不要说你如何产生多个请求所以这可能是一个问题;
  2. 您可能也会看到限制因为,在.NET 4之前,默认的最大并发请求数为16,默认并发会话数为10.这些值已在.NET 4中引发但您没有说出您正在使用的.NET版本