I developed a proof of concept application that query if WCF support multi-threading.
Now, all what I did is creating a service contract marked with
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple,
UseSynchronizationContext = true)]
with two operations to get fixed texts.
The first method do a Thread.Sleep
for 8 seconds to make the response delayed and the other one return data directly.
The issue I faced was when I run two instances of client application and request from the first client the method with delay and request the other method from the second client, I got a sequential response.
How can I get the response from the service while the service is busy with another request?
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
}
}
I need to call the methods GetDelayedResponse
and GetDirectResponse
at the same time and get the "fast" text before the 8 seconds ends.
Hosting application code
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();
}
}
}
Below is the code I implement it to test the case:
Server side classes,
Service's interface
namespace WCFSessionServer { [ServiceContract] public interface IService { [OperationContract] string GetDelayedResponse(); [OperationContract] string GetDirectResponse(); } }
Implementation class
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 } }
Server-side 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>
Client-side 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>