WCF服务不是多线程的 [英] WCF service is not multithreaded

查看:73
本文介绍了WCF服务不是多线程的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计WPF应用程序使用的WCF服务. 该服务将由50个客户端使用,并托管在多核服务器上.这就是为什么我希望它是多线程的.

I'm designing a WCF service used by a WPF application. The service will be used by 50 clients and hosted on a multi core server. That's why I would like it to be multi threaded.

这是我的声明方式:

[ServiceContract(
    SessionMode = SessionMode.Required,
    Namespace = Constants.NameSpace,
    CallbackContract = typeof (ISaphirServiceCallback))]
public interface ISaphirService


[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
                InstanceContextMode=InstanceContextMode.PerSession)]
public partial class SaphirService : ISaphirService

和服务器端配置:

  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NewBinding0" receiveTimeout="00:59:00" sendTimeout="00:59:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="20000000">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <reliableSession ordered="true" inactivityTimeout="00:30:00" enabled="true"/>
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </netTcpBinding>

      <customBinding>
        <binding name="ServicePECB2ServiceBinding">
          <textMessageEncoding messageVersion="Soap12WSAddressing10" />
          <httpsTransport />
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="https://qualiflps.services-ps.ameli.fr/lps" binding="customBinding" bindingConfiguration="ServicePECB2ServiceBinding" contract="ServiceReference1.ServicePECB2Service" name="ServicePECB2Service" />
    </client>

    <behaviors>
      <serviceBehaviors>
        <behavior name="NewBehavior0">
          <serviceThrottling maxConcurrentCalls="50" maxConcurrentSessions="50" maxConcurrentInstances="50"/>
          <serviceAuthorization serviceAuthorizationManagerType="Service.Authorizations.AuthorizationPolicy, Service">
            <authorizationPolicies>
              <add policyType="Service.Authorizations.AuthorizationPolicy, Service" />
            </authorizationPolicies>
          </serviceAuthorization>
          <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:80/Service" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <serviceCertificate storeLocation="CurrentUser" storeName="TrustedPeople" x509FindType="FindBySubjectName" findValue="*****" />
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Service.Authorizations.CustomValidator, Service" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="NewBehavior0" name="Service.Services.SaphirService">
        <endpoint address="basic" binding="netTcpBinding" bindingConfiguration="NewBinding0" contract="ServiceInterfaces.IServices.ISaphirService">
          <identity>
            <dns value="*****" />
          </identity>
        </endpoint>
      </service>
    </services>
  </system.serviceModel>

这是客户端配置:

  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_ISaphirService" receiveTimeout="00:30:00" sendTimeout="00:05:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="20000000">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <reliableSession ordered="true" inactivityTimeout="00:30:00" enabled="true"/>
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="http://****:4224/service/basic" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ISaphirService" contract="ISaphirService" name="NetTcpBinding_ISaphirService" behaviorConfiguration="CustomBehavior">
        <identity>
          <certificate encodedValue="****" />
        </identity>
      </endpoint>
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="CustomBehavior">
          <clientCredentials>
            <serviceCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust" />
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

问题是,每个请求都在同一线程上处理. 我在互联网上检查了很多,但是一切对我来说似乎都是好...

The thing is, each request are processed on the same Thread. I checked a lot on the Internet but everything seems good to me...

你们有什么主意吗?

谢谢!

推荐答案

打开ServiceHost时,WCF会捕获当前的SynchronizationContext,并将其用于所有调用. WPF的同步上下文将每个调用都发布到Dispatcher队列,该队列最终在UI线程上执行.

When opening a ServiceHost WCF captures the current SynchronizationContext, and uses it for all calls. WPF's synchronization context posts every call to the Dispatcher queue, which ends up executing on the UI thread.

您有两个选择:

  • 在没有同步上下文的其他线程上启动服务.这样做还有一个好处,就是不会阻止UI线程等待服务加载.例如,您可以使用:

  • Start the service on a different thread that doesn't have a synchronization context. This has the additional advantage of not blocking the UI thread waiting for the service to load. For example, you can use:

Task.Run(() => serviceHost.Open());

  • 指定该服务不应使用同步上下文:

  • Specify that the service should not use the synchronization context:

    [ServiceBehavior(UseSynchronizationContext = false)]
    

  • 请注意,如果您在服务方法中修改UI对象,则可能需要自己将它们分派回UI线程.

    Note that if you modify UI objects in service methods, you might need to dispatch them back to the UI thread yourself.

    这篇关于WCF服务不是多线程的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆