Desarrollé una aplicación de prueba de concepto que pregunta si WCF soporta multi-threading.¿WCF es compatible con Multi-threading?
Ahora, todo lo que hice es la creación de un contrato de servicio marcado con
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple,
UseSynchronizationContext = true)]
con dos operaciones para obtener textos fijos. El primer método hace un Thread.Sleep
durante 8 segundos para retrasar la respuesta y el otro devolver datos directamente.
El problema al que me enfrenté fue cuando ejecuto dos instancias de aplicación cliente y solicito del primer cliente el método con retraso y solicito el otro método del segundo cliente, obtengo una respuesta secuencial.
¿Cómo puedo obtener la respuesta del servicio mientras el servicio está ocupado con otra solicitud?
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
}
}
Tengo que llamar a los métodos GetDelayedResponse
y GetDirectResponse
al mismo tiempo y obtener el texto "rápida" antes de que termine el 8 segundos.
Hosting código de la aplicación
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();
}
}
}
A continuación se muestra el código que ponerlo en práctica para probar el caso: las clases laterales
Server,
Servicio de interfaz
namespace WCFSessionServer { [ServiceContract] public interface IService { [OperationContract] string GetDelayedResponse(); [OperationContract] string GetDirectResponse(); } }
clase de implementación
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 } }
-lado del servidor 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>
-lado del cliente 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>
¡DEJAR DE GRITAR, POR FAVOR! –