How do I set ReliableSession.MaxPendingChannels when I create a NetTcpBinding in code?
Asked Answered
D

4

3

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.

Dupaix answered 10/3, 2010 at 14:17 Comment(0)
D
6

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);
Dupaix answered 10/3, 2010 at 16:14 Comment(1)
Works perfectly, but there is no need to create a CustomBinding; simply setting the MaxPendingChannels on the ReliableSessionBindingElement of the basebinding is sufficient.Watt
M
2

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

Mortimer answered 3/9, 2014 at 21:1 Comment(0)
Y
0

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

Yu answered 5/8, 2014 at 10:49 Comment(0)
P
0

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);
Polyzoarium answered 24/8, 2016 at 11:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.