WCF - 为每个调用创建新通道 - 为什么此代码失败?

时间:2011-06-14 10:44:05

标签: wcf

我正在尝试制作异步WCF调用。我正在考虑多次拨打同一个服务。

从客户端我为每个呼叫创建一个新频道,进行呼叫(给它一个回调方法),然后在回调中关闭频道。

在服务中,我添加了对thread.sleep的调用,以模拟服务做一些工作。

前20个左右的呼叫完成正常(此号码每次都有所不同)。因此,在看似随机数量的呼叫之后,我在客户端上收到此异常:

无法连接到net.tcp:// localhost:61501 / Calulator。连接尝试持续时间跨度为00:00:02.9332933。 TCP错误代码10061:无法建立连接,因为目标计算机主动拒绝它127.0.0.1:61501。

所以我有几个问题:

  1. 我是正确的开新 每个电话的频道?
  2. 导致此异常的原因是什么?
  3. 非常感谢您的任何帮助。

    我的代码如下,也可以在这里找到: https://subversion.assembla.com/svn/agilenet/tags/WcfStackOverflow/Wcf

    服务:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace Service
    {
        class Program
        {
            static void Main(string[] args)
            {
                NetTcpBinding netBinding = new NetTcpBinding();
    
                ServiceHost host = null;
                host = new ServiceHost(
                        typeof(Calculator),
                        new Uri("net.tcp://localhost:61501/Calulator"));
                host.AddServiceEndpoint(
                        typeof(ICalculator),
                        netBinding,
                        string.Empty);
                host.Open();
    
                Console.ReadLine();
            }
        }
    
        [ServiceContract]
        public interface ICalculator
        {
            [OperationContract]
            int Add(int value1, int value2);
    
            [OperationContract(AsyncPattern = true)]
            IAsyncResult BeginAdd(int value1, int value2, AsyncCallback callback, object state);
    
            int EndAdd(IAsyncResult result);
        }
    
        public class Calculator : ICalculator
        {
            public int Add(int value1, int value2)
            {
                Console.WriteLine(
                    "Incoming Add request {0}, {1}",
                    value1.ToString(),
                    value2.ToString());
                System.Threading.Thread.Sleep(500);
                return value1 + value2;
            }
    
            public IAsyncResult BeginAdd(int value1, int value2, AsyncCallback callback, object state)
            {
                throw new NotImplementedException();
            }
    
            public int EndAdd(IAsyncResult result)
            {
                throw new NotImplementedException();
            }
    
        }
    }
    

    客户端:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using Service;
    
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                NetTcpBinding netBinding = new NetTcpBinding();
                ChannelFactory<ICalculator> factory = new ChannelFactory<ICalculator>(
                    netBinding,
                    "net.tcp://localhost:61501/Calulator");
    
                for (int i = 0; i < 100; i++)
                {
                    ICalculator service = factory.CreateChannel();
                    service.BeginAdd(i, 0, SaveCallback, service);
                }
    
                Console.ReadLine();
            }
    
            static void SaveCallback(IAsyncResult ar)
            {
                ICalculator service = (ICalculator)ar.AsyncState;
                Console.WriteLine(service.EndAdd(ar).ToString());
                ((IContextChannel)service).Close();
    
            }
    
        }
    
    }
    

1 个答案:

答案 0 :(得分:1)

我认为你遇到过windows(7 / Vista / XP)tcp连接限制。这些操作系统:将(入站)tcp连接数限制为20.谷歌搜索“windows tcp连接限制”为您提供了有关该主题的更多信息。

SuperUser还有一个关于这个主题的主题:https://superuser.com/questions/253141/inbound-tcp-connection-limit-in-windows-7。更多信息也在ServerFault(从SU链接)。

所以回答你的问题:

  1. 不,您不应为每次通话打开新频道。
  2. 您达到了非服务器版本的Windows(可能是7或Vista,因为您可以获得20个连接)的限制。您可以获得随机数量的成功连接,因为有时候操作系统足够快,可以清理少量第一个连接,但请求率非常高,最终会达到最大值。