Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different timeouts for different requests to the same WCF service

I have a WCF service with https bindings and a callback. The service is referenced in the client as a service reference. The timeouts are defined in the config files for both the service and the client.

I need a function in the service to be called with smaller time-out values than the default value used for the other functions.

The code for my client looks like following

MyService.MyServiceClient myServiceClient = new MyService.MyServiceClient(context);
myServiceClient.GenericSendData("Save Req", serializedString, ServerIdentifier, null);

How can I change my code in the client/server to use smaller timeout values for requests to specific functions? Can I specify and change the timeouts in the code according to the function which I am calling?

like image 830
puneet Avatar asked Oct 14 '14 11:10

puneet


People also ask

How many requests can a WCF service handle?

By default, a WCF service handles only one request at a given moment of time.

What is the default timeout for WCF service?

The most common default timeout values within Archiver are: 2 min for querying the Microsoft SQL Server. 5 min for WCF connections (This is used heavily for internal communication between GFI Archiver's own modules).

What is ReceiveTimeout in WCF service?

ReceiveTimeout – used by the Service Framework Layer to initialize the session-idle timeout which controls how long a session can be idle before timing out.


2 Answers

Yes. Just set SendTimeout on your client. To set a 10 second timeout for a particular service call you can use this sample:

using(MyService.MyServiceClient myServiceClient = new MyService.MyServiceClient(context))
{
    myServiceClient.Endpoint.Binding.SendTimeout = TimeSpan.FromSeconds(10);
    myServiceClient.GenericSendData("Save Req", serializedString, ServerIdentifier, null);
}
like image 125
brz Avatar answered Sep 26 '22 03:09

brz


Regarding the client, you can manipulate the binding programmatically and set the client timeouts for each service client instance. The idea is to have different binding configurations, and then pass the binding needed in the ServiceClient constructor.

Here is an example of instantiating a BasicHttpBinding object, setting 30 second timeouts for the first service client instance, and then changing timeouts to 5 seconds for the next service client instance:

var customBinding = new BasicHttpBinding()
{
    ReceiveTimeout = TimeSpan.FromSeconds(30), 
    SendTimeout = TimeSpan.FromSeconds(30),
    CloseTimeout = TimeSpan.FromSeconds(30),
    OpenTimeout = TimeSpan.FromSeconds(30) 
};

var endpointAddress = new EndpointAddress("http://localhost:6670/Service1.svc");

using (var client = new Service1Client(customBinding, endpointAddress))
{
    var data = client.GetData(100);
}

customBinding.OpenTimeout = TimeSpan.FromSeconds(5);
customBinding.CloseTimeout = TimeSpan.FromSeconds(5);
customBinding.SendTimeout = TimeSpan.FromSeconds(5);
customBinding.ReceiveTimeout = TimeSpan.FromSeconds(5);

using (var client = new Service1Client(customBinding, endpointAddress))
{
    var data = client.GetData(101);
}

Alternatively you can do it through configuration:

<system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_IService1_Shorter" openTimeout="00:00:05"
     closeTimeout="00:00:05"
     sendTimeout="00:00:05"
     receiveTimeout="00:00:05"/>
    <binding name="BasicHttpBinding_IService1_Longer" openTimeout="00:00:30"
       closeTimeout="00:00:30"
       sendTimeout="00:00:30"
       receiveTimeout="00:00:30"/>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost:6670/Service1.svc" binding="basicHttpBinding"
      bindingConfiguration="BasicHttpBinding_IService1_Longer" contract="ServiceReference1.IService1"
      name="BasicHttpBinding_IService1_Longer" />
  <endpoint address="http://localhost:6670/Service1.svc" binding="basicHttpBinding"
      bindingConfiguration="BasicHttpBinding_IService1_Shorter" contract="ServiceReference1.IService1"
      name="BasicHttpBinding_IService1_Shorter" />
</client>
</system.serviceModel>

And then you would instantiate the clients to use different configurations:

 using (var client = new Service1Client("BasicHttpBinding_IService1_Longer"))
 {
     var data = client.GetData(100);
 }

 using (var client = new Service1Client("BasicHttpBinding_IService1_Shorter"))
 {
     var data = client.GetData(101);
 }

Regarding the server, it is not possible, and definitely not a good idea to change timeouts of a running WCF service on a per-request basis, and it doesn't make sense. One possibility could be to have different endpoints covering different operations, and each endpoint could have different server timeout settings.

like image 45
Faris Zacina Avatar answered Sep 29 '22 03:09

Faris Zacina