zoukankan      html  css  js  c++  java
  • WCF实例与并发的一些测试

    环境.net4.0 使用NetTcpBinding

    概要

    实例管理可以理解为服端怎么管理(创建与销毁)Service 类的实例
    并发可以理解为WCF框架在收到客户端请求后针对目标Service实例的派发行为,Single表现为如果Service已经在处理请求了,那么新的请求(注意是针对同一个Service实例的)将排队,如果是Mutiple那么请求将立即执行,其实质是请求的处理基于同一个Service实例的锁定同步行为。

    进一步说明,WCF针对请求的处理是基于池线程的,当使用NetTcp的同个proxy(对应物理上的一Tcp链接)发出多个请求时,如果服务器使用的是PerCall+Single组合,那么该条TCP链接的请求将串行华处理(无法说是分配一个固定线程处理,因观察到同个proxy,50个并发请在两个线程上运行--指更换过一次线程)。

    //==========测试代码服务端=============

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.Threading;
    namespace WCFServer
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                var timer = new Timer((o) => { GC.Collect(); }, null, 0, 100);
    
                using(ServiceHost host=new ServiceHost(typeof(CalculatorService)))
                {
                    host.AddServiceEndpoint(typeof(ICalculator), new NetTcpBinding(),
                    "net.tcp://192.168.1.31:8888/CalculatorService");
                    host.Opened += (s,e) => {
                        Console.WriteLine("服务启动!");
                    };
                    host.Open();
                    Console.Read();
    
                }
            }
        }
    
    
        [ServiceContract]
        public interface ICalculator
        {
            [OperationContract]
            int Add(int x, int y);
        }
    
    
        [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single,ConcurrencyMode=ConcurrencyMode.Single)]
        public class CalculatorService : ICalculator,IDisposable
        {
    
            public CalculatorService()
            {
                Console.WriteLine( AddThreadMsg( "Instantiated!"));
            }
    
            public int Add(int x, int y)
            {
                Console.WriteLine(AddThreadMsg( string.Format("index:{0}, Time:{1}, Operation method is invoked.",x,DateTime.Now)));
               Thread.Sleep(1000);
                return x + y;
            }
    
            ~CalculatorService()
            {
                Console.WriteLine(AddThreadMsg( "Finalized!"));
            }
    
            public void Dispose()
            {
                Console.WriteLine(AddThreadMsg( "Dispose!"));
            }
            private string AddThreadMsg(string msg)
            {
                return msg + ",ThreadId:" + Thread.CurrentThread.ManagedThreadId;
            }
        }
    }

    //==========测试代码客户端=============

    View Code
     static void Main(string[] args)
            {
                using (ChannelFactory<ICalculator> channelFac =
                    new ChannelFactory<ICalculator>(new NetTcpBinding(),
                    "net.tcp://192.168.1.31:8888/CalculatorService"))
                {
                    var proxy = channelFac.CreateChannel();
                    if (null != proxy as ICommunicationObject)
                    {
                        (proxy as ICommunicationObject).Open();
                    }
            
                    Random rnd=new Random();
                    for (int i = 1; i < 50; i++)
                    {
                        var index = i;
                       Thread t=new Thread(()=>{
                           try
                           {
                               Thread.Sleep(rnd.Next(100, 10000));
    
                 
                               Console.WriteLine(string.Format("{3}:{0}+{1}={2}", index, 2, proxy.Add(index, 2), index));
                               //(proxy as ICommunicationObject).Close();
                           }
                           catch (Exception ex)
                           {
                               Console.WriteLine(string.Format("Error-{0}:{1}", index, ex.Message));
                           }
                   
                            
                       });
                       t.Start();
    
                        
                    }
    
                    Console.Read();
                }
    
                Console.WriteLine("完成");
                Console.Read();
            }
    
        }

    //说明

    1.在使用NetTcpBinding时,一个客户端proxy跟一条连接对应(可以通过创建多个proxy模拟多个客户端),在调用open后,可以通过netstat命令看到建立的TCP 连接。

    2.当使用多线程模拟多个并发的链接时(proxy),服务器默认只能并行的接收11个连接,这个跟socket编程时监听端口允许并发的链接数设置一致。

    3.PerCall + Mutiple时,建立一个proxy在未打开的情况下在多个线程中调用,proxy会根据调用先后对这些调用请求进行串行华处理。

    4.PerCall + Mutiple时,建立多个proxy进行并发调用,服务器表现是并行处理请求。

    5.PerCall + Single时,建立多个proxy并发请求时,服务器呈现并行处理,而单个proxy并发请求时,服务器呈现串行处理,当把NetTcpBingding换成BasicHttpBinding时服务器又变为出并行处理,不过可以通过netstat看到,使用http协议后单个proxy的并发调用实际上是建立了多个tcp连接的,
    可见PerCall +Single时针对同个链接发来的请求是串行处理的

     6.针对同一个客户端代理的并发调用,其请求会在客户端被串行后发出。不支持回话的信道绑定不受会话节流阀限制

    参考:

    http://www.cnblogs.com/tyb1222/archive/2012/05/23/2515535.html

  • 相关阅读:
    November 13th 2016 Week 47th Sunday The 1st Day
    November 12th 2016 Week 46th Saturday
    November 11th 2016 Week 46th Friday
    November 10th 2016 Week 46th Thursday
    November 9th 2016 Week 46th Wednesday
    November 8th 2016 Week 46th Tuesday
    windows 7文件共享方法
    Win7无线网络共享设置方法
    常量指针和指针常量
    如何查找局域网的外网ip
  • 原文地址:https://www.cnblogs.com/wdfrog/p/2517443.html
Copyright © 2011-2022 走看看