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

三世轮回 提交于 2019-12-10 18:14:13

问题


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.


回答1:


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);



回答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




回答3:


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




回答4:


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);


来源:https://stackoverflow.com/questions/2417496/how-do-i-set-reliablesession-maxpendingchannels-when-i-create-a-nettcpbinding-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!