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>
Multithreading in C# is a process in which multiple threads work simultaneously. It is a process to achieve multitasking. It saves time because multiple tasks are being executed at a time. To create multithreaded application in C#, we need to use System.
To overcome that situation, VB.NET introduces a new concept Multithreading to execute multiple tasks at the same time by creating multiple threads in a program.
There are three concurrency modes available: Single : Each service instance processes one message at a time. This is the default concurrency mode. Multiple : Each service instance processes multiple messages concurrently. The service implementation must be thread-safe to use this concurrency mode.
ASP.NET platform is multithreaded by its nature and provides programming models that shield us from the complexity of using threads.
Try to change the value of the attribute
UseSynchronizationContext=false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With