难道WCF服务使用多线程来处理传入的请求?多线程、WCF

2023-09-03 20:25:14 作者:青杉依旧

我怎样才能确保WCF服务使用线程一个线程池来处理传入的消息?

在像此刻简单的方法调用'返回NULL;'需要约45秒,而另一个请求被处理

下面是我如何注解我的服务类:

  [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,InstanceContextMode = InstanceContextMode.Single)
    公共部分类的MyService:IMyService {
...
}
 

但是,当我在看的过程中任务管理器这似乎是使用线程的数量不变。即使是在负载下。

 公众的ActionResult SelectDatabase(字符串参数)
        {
            如果(!String.IsNullOrEmpty(参数))
            {
            尝试
            {
                MyServicece SVC =新的MyService();
                数据库[] dbsArray = svc.GetDatabases(参数);
                如果(depsArray!= NULL)
                    计算机[depsArray] = depsArray;

                返回查看();
            }
            赶上(例外EXC)
            {
                //这里登录
                返回ActionUnavailable();
            }
        }
 
Creating DSS Service Projects

下面是我的服务行为:

 < XML版本=1.0&GT?;
<结构>
  <运行>

  < /运行>
  < system.net>
    < connectionManagement>
      <新增地址=*maxconnection =100/>
    < / connectionManagement>
  < /system.net>
  < system.serviceModel>
    <诊断performanceCounters =默认/>
    <绑定>
      < NetTcpBinding的>
        <结合的SendTimeout =00:02:00receiveTimeout =00:02:00maxBufferSize =2147483647maxReceivedMessageSize =2147483647maxBufferPoolSize =2147483647>
          <安全模式=无>
          < /安全>
        < /装订>
      < / NetTcpBinding的>
    < /绑定>
    < serviceHostingEnvironment aspNetCompatibilityEnabled =真/>
    <行为>
      < endpointBehaviors>
        <行为NAME =CrossDomainServiceBehavior>
          < webHttp />
        < /行为>
      < / endpointBehaviors>
      < serviceBehaviors>
        <行为NAME =MyService.MyServiceBehavior>
          < serviceThrottling maxConcurrentCalls =100maxConcurrentInstances =100maxConcurrentSessions =100/>
          < D​​ataContractSerializer的maxItemsInObjectGraph =2147483646/>
          < serviceMetadata httpGetEnabled =FALSE/>
          < serviceDebug includeExceptionDetailInFaults =真/>
        < /行为>
      < / serviceBehaviors>
    < /行为>
    <服务>
      <服务behaviorConfiguration =MyService.MyServiceBehaviorNAME =MyService.MyService>
        <端点地址=为MyService绑定=NetTcpBinding的合同=AService.IAServisSystemEndpoint =FALSE/>
        <端点地址=MEX绑定=mexTcpBinding合同=IMetadataExchange接口/>
      < /服务>
      <服务behaviorConfiguration =MyService.MyServiceBehaviorNAME =MyService.MyServiceAdmin>
        <端点地址=MyServiceAdmin绑定=NetTcpBinding的合同=MyService.IMyServiceAdminisSystemEndpoint =FALSE/>
        <端点地址=MEX绑定=mexTcpBinding合同=IMetadataExchange接口/>
      < /服务>
    < /服务>
  < /system.serviceModel>
<启动>< supportedRuntime版本=4.0版的SKU = /&GTNETFramework,版本= V4.0。;< /启动>< /结构>
 

下面是如何创建服务实例:

 的ServiceHost myserviceHost =新的ServiceHost(typeof运算(为MyService),新的URI(的String.Format(的net.tcp:// {0} /,_bindAddress)));
            myserviceHost.Open();
            Console.WriteLine(myserviceHost.BaseAddresses [0]);
 

解决方案

InstanceContextMode和ConcurrencyMode是不同的概念,但其中有相互影响的程度 - 我的博客上讲述这个在一些深度而回

WCF调用的IO处理线程池线程。假设你有没有做过类似 ConcurrencyMode.Single InstanceContextMode.Single 将每个呼叫序列化为服务线程池管理器将尝试线程数平衡到工作速度。

如果并发请求的数目可以由5线程提供服务那么这是多少,将使用。您可能会看到该线程池能够跟上工作的你可以看到线程数的比率。你可以很愉快地使用比内核和效果更多的线程,因为,只要线程是不是纯粹的CPU限制,操作系统可以通过线程切换到CPU时,previously正在运行的线程启动的IO获得的吞吐量。如果CPU是完全max'd出那么线程池管理器的启发式将使沉默寡言添加更多的线程进入线程池

但是,也有另几个潜在的问题:

基于会话的绑定可以在客户机侧阻断,与此同时有通过相同的代理多个并发出站请求。你不;吨说,你是如何生成的多个请求所以这可能是一个问题; 您也可以看到节流为踢,到.NET 4的并发请求的默认的最大数量为16个并发会话的默认数量是10个。这些价值观已经在.NET 4中被提出之前,但你不知道说哪个.NET版本使用的是

How can I ensure that a WCF service uses threads from a ThreadPool to process incoming messages?

At the moment simple method invocation like 'return null;' takes about 45 seconds while another requests are processing

Here is how I have annotated my service class:

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

But when I'm watching the process in task manager it seems to be using a constant number of threads. Even under load.

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();
            }
        }

Here is my service behavior:

<?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>

Here is how I create service instance:

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

解决方案

InstanceContextMode and ConcurrencyMode are separate concepts but which have a level of interplay - I blogged about this in some depth a while back

WCF calls are processed on IO threadpool threads. Assuming you haven't done something like ConcurrencyMode.Single, InstanceContextMode.Single which will serialize every call into the service the threadpool manager will try to balance the number of threads to the rate of work.

If the number of concurrent requests can be serviced by 5 threads then that's how many it will use. You may be seeing that the threadpool can keep up with the rate of work with the number of threads you can see. You can quite happily use more threads than cores with effect because, as long as the threads are not purely CPU bound, the OS can gain throughput by switching threads onto the CPU when the previously running thread starts IO. If the CPU is completely max'd out then the heuristics of the threadpool manager will make it reticent to add more threads into the thread pool

However, there are another couple of potential issues:

Session based bindings can block on the client side while there are multiple concurrent outbound requests through the same proxy. You don;t say how you are generating the multiple requests so this may be an issue; You may also be seeing throttling kicking in as, prior to .NET 4 the default max number of concurrent requests was 16 and default number of concurrent sessions was 10. These values have been raised in .NET 4 but you don't say which version of .NET you are using

 
精彩推荐
图片推荐