【问题标题】:How do I set ReliableSession.MaxPendingChannels when I create a NetTcpBinding in code?在代码中创建 NetTcpBinding 时如何设置 ReliableSession.MaxPendingChannels?
【发布时间】:2010-03-10 14:17:15
【问题描述】:

我们收到此错误:

System.ServiceModel.ServerTooBusyException: 创建可靠的请求 会话已被 RM 拒绝 目的地。服务器 'net.tcp://localhost:50000/' 也是 忙于处理此请求。尝试 稍后再试。该频道无法 打开了。

据我了解,我需要在 ReliableSession 绑定中增加 MaxPendingChannels 的值。

但是我们在这样的代码中配置 WCF:

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

那么如何以编程方式设置 ReliableSession.MaxPendingChannels? (我能找到的所有示例都使用配置文件)


在此web page 上搜索 MaxPendingChannels 以获得一个选项,但它似乎过于复杂。

【问题讨论】:

    标签: .net wcf configuration nettcpbinding


    【解决方案1】:

    这就是我所做的:

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

    【讨论】:

    • 完美运行,但无需创建CustomBinding;只需在 basebinding 的 ReliableSessionBindingElement 上设置 MaxPendingChannels 就足够了。
    【解决方案2】:

    我还需要在代码中设置这个属性,经过研究发现有两种方法可以通过编程来完成。

    第一种方法是直接在代码中创建绑定元素,并根据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);
    

    我发现的第二种方法是从现有绑定中获取对绑定元素的引用,如此处所述How to: Customize a System-Provided Binding。这是最佳答案。

    我尝试在 NetTcpBinding 上设置 ReliableSession 属性,但它实际上并没有像我期望的那样修改 MaxPendingConnections 属性。在查看 NetTcpBinding 和 ReliableSession 的 .NET 源代码后,我发现像这样在绑定上设置此属性

    NetTcpBinding netTcpBinding = new NetTcpBinding(SecurityMode.None, true);
    
    netTcpBinding.ReliableSession = 
        new OptionalReliableSession(
            new ReliableSessionBindingElement()
                {
                    MaxPendingChannels = 100
                });
    

    实际上并未在绑定上设置 MaxPendingChannels 属性。

    我最终直接从绑定元素创建绑定,因为我想精确控制绑定

    【讨论】:

      【解决方案3】:

      或者您可以像这样使用NetTcpBinding 中的ReliableSession 属性的构造函数:

      // initialize ReliableSessionBindingElement object
      var reliableSessionBindingElement = new ReliableSessionBindingElement
      {
        MaxPendingChannels = 128
        // set other properties here
      }; 
      
      binding.ReliableSession = new ReliableSession(reliableSessionBindingElement)
      {
        // set properties here
      };
      

      更多信息请见:http://msdn.microsoft.com/en-us/library/ms585454(v=vs.110).aspx

      【讨论】:

        【解决方案4】:

        如果你使用像 NetTcpRelayBinding 这样的中继绑定,你可以使用以下代码:

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

        用法:

        var binding = new NetTcpRelayBinding();
        binding.SetReliableSessionMaxPendingChannels(128);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-10-03
          • 2022-10-07
          • 1970-01-01
          • 1970-01-01
          • 2020-12-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多