Question

We are getting this error:

System.ServiceModel.ServerTooBusyException: The request to create a reliable session has been refused by the RM Destination. Server 'net.tcp://localhost:50000/' is too busy to process this request. Try again later. The channel could not be opened.

As I understand it, I need to increase the value of MaxPendingChannels in the ReliableSession binding.

However we configure WCF in code like this:

serviceHost = new ServiceHost(typeof(MyServiceClass));
ServiceEndpoint endPoint = serviceHost.AddServiceEndpoint(
    typeof(IMyService),
    new NetTcpBinding(SecurityMode.None, true),
    endPointAddress);

So how do I set ReliableSession.MaxPendingChannels programmatically? (All the examples I can find use config files)


Search for MaxPendingChannels on this web page for one option, but it seems over complex.

Was it helpful?

Solution

This is what I did:

 private Binding CreateBindingWith_MaxPendingChannels_Set(Binding baseBinding)
 {
     BindingElementCollection elements = baseBinding.CreateBindingElements();
     ReliableSessionBindingElement reliableSessionElement = 
                elements.Find<ReliableSessionBindingElement>();
     if (reliableSessionElement != null)
     {
         reliableSessionElement.MaxPendingChannels = 128;

         CustomBinding newBinding = new CustomBinding(elements);

         newBinding.CloseTimeout = baseBinding.CloseTimeout;
         newBinding.OpenTimeout = baseBinding.OpenTimeout;
         newBinding.ReceiveTimeout = baseBinding.ReceiveTimeout;
         newBinding.SendTimeout = baseBinding.SendTimeout;
         newBinding.Name = baseBinding.Name;
         newBinding.Namespace = baseBinding.Namespace;
         return newBinding;
     }
     else
     {
         throw new Exception("the base binding does not " +
                             "have ReliableSessionBindingElement");
     }
 }

.....

 Binding customBinding = CreateBindingWith_MaxPendingChannels_Set(
      new NetTcpBinding(SecurityMode.None, true));

 serviceHost = new ServiceHost(typeof(MyService));
 ServiceEndpoint endPoint = serviceHost.AddServiceEndpoint(
                    typeof(IMyService),
                    customBinding,
                    endPointAddress);

OTHER TIPS

I also needed to set this property in code and after researching it found there are two ways to do it programmatically.

The first way is to create the binding elements directly in code, and create a new Custom Binding from them as described on the CustomBinding MSDN

// Create a custom binding that contains two binding elements.
ReliableSessionBindingElement reliableSession = new ReliableSessionBindingElement();
reliableSession.MaxPendingChannels = 100;

TcpTransportBindingElement tcpTransport = new TcpTransportBindingElement();

CustomBinding binding = new CustomBinding(reliableSession, tcpTransport);

the second way I found is to grab a reference to the binding elements from an existing binding as described here How to: Customize a System-Provided Binding. This is what the top answer is.

I tried to set the ReliableSession property on the NetTcpBinding, but it wasn't actually modifying the MaxPendingConnections property that I was expecting. After looking into the .NET source for NetTcpBinding and ReliableSession, I found that setting this property on the binding like this

NetTcpBinding netTcpBinding = new NetTcpBinding(SecurityMode.None, true);

netTcpBinding.ReliableSession = 
    new OptionalReliableSession(
        new ReliableSessionBindingElement()
            {
                MaxPendingChannels = 100
            });

Doesn't actually set the MaxPendingChannels property on the binding.

I ended up creating my binding from the binding elements directly since I wanted to precisely control the binding

Or you could use the constructor of the ReliableSession property from the NetTcpBinding like this:

// initialize ReliableSessionBindingElement object
var reliableSessionBindingElement = new ReliableSessionBindingElement
{
  MaxPendingChannels = 128
  // set other properties here
}; 

binding.ReliableSession = new ReliableSession(reliableSessionBindingElement)
{
  // set properties here
};

For more information please see: http://msdn.microsoft.com/en-us/library/ms585454(v=vs.110).aspx

If you use the relay bindings like NetTcpRelayBinding, you can use following code:

public static class NetTcpRelayBindingExtension
{
    public static void SetReliableSessionMaxPendingChannels(this NetTcpRelayBinding baseBinding, Int32 MaxPendingChannels)
    {
        var bindingType = baseBinding.GetType();
        var bindingProperty = bindingType.GetField("session", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic);
        var reliableSession = (ReliableSessionBindingElement)bindingProperty.GetValue(baseBinding);
        reliableSession.MaxPendingChannels = MaxPendingChannels;
    }
}

Usage:

var binding = new NetTcpRelayBinding();
binding.SetReliableSessionMaxPendingChannels(128);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top