gpt4 book ai didi

wcf - WCF 本身是否支持多线程?

转载 作者:行者123 更新时间:2023-12-04 01:50:12 27 4
gpt4 key购买 nike

我开发了一个概念验证应用程序,用于查询 WCF 是否支持多线程。

现在,我所做的就是创建一个标有

 [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple,
UseSynchronizationContext = true)]

通过两个操作来获取固定文本。
第一种方法做一个 Thread.Sleep 8秒使响应延迟,另一个直接返回数据。

我面临的问题是,当我运行两个客户端应用程序实例并从第一个客户端请求延迟的方法并从第二个客户端请求另一个方法时,我得到了顺序响应。

当服务忙于另一个请求时,如何从服务中获得响应?
 namespace WCFSyncService
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)],
ConcurrencyMode = ConcurrencyMode.Multiple,
UseSynchronizationContext = true)]

public class ServiceImplementation : IService

{
public ServiceImplementation()
{
}

#region IService Members

public string GetDelayedResponse()
{
System.Threading.Thread.Sleep(8000);
return "Slow";
}

public string GetDirectResponse()
{
return "Fast";
}

#endregion
}
}

我需要调用方法 GetDelayedResponseGetDirectResponse同时并在 8 秒结束前获取“快速”文本。

托管应用程序代码
namespace ServiceHostApplication
{
public partial class frmMain : Form
{
private WCFSessionServer.IService oService;

public frmMain()
{
InitializeComponent();
}

private void btnStartService_Click(object sender, EventArgs e)
{
ServiceHost objSvcHost;

oService = new WCFSessionServer.ServiceImplementation();
objSvcHost = new ServiceHost( typeof(WCFSessionServer.ServiceImplementation));
objSvcHost.Open();
}
}
}

下面是我实现它来测试案例的代码:

服务器端类,
  • 服务界面
    namespace WCFSessionServer
    {
    [ServiceContract]
    public interface IService

    {
    [OperationContract]
    string GetDelayedResponse();

    [OperationContract]
    string GetDirectResponse();
    }
    }
  • 实现类
    namespace WCFSessionServer
    {
    [ServiceBehavior(
    InstanceContextMode = InstanceContextMode.PerCall,
    ConcurrencyMode = ConcurrencyMode.Multiple,
    UseSynchronizationContext = true)]
    public class ServiceImplementation : IService
    {
    public ServiceImplementation()
    {
    }

    #region Service Members
    public string GetDelayedResponse()
    {
    System.Threading.Thread.Sleep(8000);
    return "Slow";
    }

    public string GetDirectResponse()
    {
    return "Fast";
    }
    #endregion
    }
    }
  • 服务器端 app.config
    <system.serviceModel>
    <services>
    <service
    behaviorConfiguration = "WCFSessionServer.IService"
    name = "WCFSessionServer.ServiceImplementation" >
    <endpoint address="http://localhost:2020/SessionService/basic/"
    behaviorConfiguration="WCFSessionServer.IService"
    binding="basicHttpBinding"
    name="BasicHttpBinding_IService"
    bindingName="myBasicHttpBinding"
    contract="WCFSessionServer.IService" />
    <endpoint address="mex"
    binding="mexHttpBinding"
    contract="IMetadataExchange" />
    <host>
    <baseAddresses>
    <add baseAddress="http://localhost:2020/SessionService/" />
    </baseAddresses>
    </host>
    </service>
    </services>
    <behaviors>
    <endpointBehaviors>
    <behavior name="TimeOut">
    <callbackTimeouts transactionTimeout="00:00:02"/>
    </behavior>
    <behavior name="WCFSessionServer.IService" >
    <dataContractSerializer maxItemsInObjectGraph="2147483647" />
    </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
    <behavior name="WCFSessionServer.IService">
    <serviceThrottling maxConcurrentCalls="10"
    maxConcurrentSessions="10"
    maxConcurrentInstances="10"/>
    <dataContractSerializer maxItemsInObjectGraph="2147483647" />
    <serviceMetadata httpGetEnabled="True"/>
    <serviceDebug includeExceptionDetailInFaults="True" />
    </behavior>
    </serviceBehaviors>
    </behaviors>
    </system.serviceModel>

  • 客户端 app.config
        <system.serviceModel>
    <bindings>
    <basicHttpBinding>
    <binding name="BasicHttpBinding_IService"
    closeTimeout="00:01:00"
    openTimeout="00:01:00"
    receiveTimeout="00:10:00"
    sendTimeout="00:01:00"
    allowCookies="false"
    bypassProxyOnLocal="false"
    hostNameComparisonMode="StrongWildcard"
    maxBufferSize="65536"
    maxBufferPoolSize="524288"
    maxReceivedMessageSize="65536"
    messageEncoding="Text"
    textEncoding="utf-8"
    transferMode="Buffered"
    useDefaultWebProxy="true">
    <readerQuotas maxDepth="32"
    maxStringContentLength="8192"
    maxArrayLength="16384"
    maxBytesPerRead="4096"
    maxNameTableCharCount="16384" />
    <security mode="None">
    <transport
    clientCredentialType="None"
    proxyCredentialType="None"
    realm="" />
    <message
    clientCredentialType="UserName"
    algorithmSuite="Default" />
    </security>
    </binding>
    </basicHttpBinding>
    </bindings>
    <client>
    <endpoint address="http://localhost:2020/SessionService/basic/"
    binding="basicHttpBinding"
    bindingConfiguration="BasicHttpBinding_IService"
    contract="SessionServiceProxy.IService"
    name="BasicHttpBinding_IService" />
    </client>
    </system.serviceModel>

    最佳答案

    好吧,通过定义你的服务

    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, 
    ConcurrencyMode=ConcurrencyMode.Multiple,
    UseSynchronizationContext=true)]

    您基本上将您的服务类定义为单例( InstanceContextMode.Single ),这当然不是最好的方法。通过将其定义为 ConcurrencyMode.Multiple ,你使它成为一个多线程的单例——这把确保你的代码 200% 线程安全的很多负担放在你自己的肩上。

    我的建议是将您的服务实现类标记为每次调用。
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall, 
    ConcurrencyMode=ConcurrencyMode.Single)]

    使用这种方法,WCF 运行时本身将根据需要启动尽可能多的服务实例类来处理您的请求。在您的示例中,WCF 运行时将创建并启动 ServiceImplementation 的两个实例。 ,每个请求一个,并发处理调用。最大的优点是:由于每个服务实例类只处理一个请求,因此您无需担心代码中的并发管理——您在一个“单线程”类中,WCF 运行时处理与有多个请求并适本地处理它们。

    更新:你还在 不是 展示如何创建客户端服务代理,以及如何调用服务。您已经发布了几乎所有的服务器端代码 - 但没有发布任何客户端代码。

    好的,这是如何做到的:
  • 启动您的服务主机并确保它正在运行
  • 在 Visual Studio 中,为您的客户端创建两个单独的控制台应用程序项目 - 将它们命名为 Client1Client2
  • 在这两个新客户项目中,使用 Add Service Reference为您的服务添加服务引用
  • 这将在“服务引用”地球下创建一堆文件
  • 您现在需要在两个客户端项目中实例化客户端代理的实例:
     In Client1:
    var instance1 = new ServiceImplementationClient();

    In Client2:
    var instance2 = new ServiceImplementationClient();
  • Client1将调用您的第一个方法 GetDelayedResponse , 而 Client2将调用 GetDirectResponse :
     In Client1:
    instance1.GetDelayedResponse();

    In Client2:
    instance2.GetDirectResponse();
  • 如果您同时运行这两个应用程序,您应该看到 Client2立即返回,同时 Client1将等待那 8 秒。

  • 如果您有两个完全独立的客户端,并且它们将在服务器上获得一个完全独立的服务实例,则它们彼此完全独立,不会序列化它们的调用,也不会相互阻塞。

    关于wcf - WCF 本身是否支持多线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3295045/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com