private void ProcessDisconnectAndCloseSocket(SocketAsyncEventArgs receiveSendEventArgs)
        {
            try
            {
                ClientUserToken receiveSendToken = (ClientUserToken)receiveSendEventArgs.UserToken;

                //This method closes the socket and releases all resources, both
                //managed and unmanaged. It internally calls Dispose.
                receiveSendEventArgs.AcceptSocket.Close();

                //create an object that we can write data to.
                receiveSendToken.CreateNewSendDataHolder();

                receiveSendToken.isReuseConnection = false;

                // It is time to release this SAEA object.
                this.poolOfRecSendEventArgs.Push(receiveSendEventArgs);
            }
            catch (Exception shutdownErr)
            {
                LogManager.Log(string.Empty, shutdownErr);
            }
            finally
            {
                this.maxConcurrentConnection.Release();
                Interlocked.Decrement(ref currentConnectionCount);
                GetSimplePerf().PerfConcurrentClientConnectionCounter.Decrement();
            }
        }
        private bool ReuseHeartBeatSAEA(List <Message> messages, string serverEndPointKey)
        {
            try {
                if (!dictPoolOfHeartBeatRecSendEventArgs.ContainsKey(serverEndPointKey))
                {
                    return(false);
                }

                SocketAsyncEventArgPool thisPortSocketPool = dictPoolOfHeartBeatRecSendEventArgs[serverEndPointKey];

                //while (!thisPortSocketPool.IsEmpty)
                while (true)
                {
                    cleanSignal.Reset();

                    //鉴于IsEmpty有问题,确保有Pop尝试!
                    SocketAsyncEventArgs arg = thisPortSocketPool.Pop();

                    if (arg == null)
                    {
                        if (thisPortSocketPool.IsEmpty)
                        {
                            LogManager.LogTraceInfo(string.Format("poolKey:{0} 's pool empty now with count:{1}", serverEndPointKey, thisPortSocketPool.Count));
                            return(false);
                        }
                        else
                        {
                            Thread.Sleep(1);
                            continue;
                        }
                    }

                    GetSimplePerf().PerfClientReuseConnectionCounter.Increment();
                    GetSimplePerf().PerfClientIdleConnectionCounter.Decrement();

                    ClientUserToken userToken = (ClientUserToken)arg.UserToken;
                    userToken.CreateNewSendDataHolder();
                    SendDataHolder sendDataHodler = userToken.sendDataHolder;

                    sendDataHodler.SetSendMessage(messages);
                    MessagePreparer.GetDataToSend(arg);
                    sendDataHodler.ArrayOfMessageToSend[0].StartTime = DateTime.Now;

                    StartSend(arg);

                    return(true);
                }
            }
            catch (Exception pickErr) {
                LogManager.Log(string.Format("pick socket from poolKey:{0} occur error!", serverEndPointKey), pickErr);
            }
            finally {
                cleanSignal.Set();
            }

            return(false);
        }
        private void Init()
        {
            if (!isInit)
            {
                lock (lockForPickObject)
                {
                    if (!isInit)
                    {
                        Stopwatch sw = new Stopwatch();

                        sw.Start();

                        clientSetting = GetLocalClientSetting();

                        ServerCount = clientSetting.serverEndPoints.Length;

                        timeOutByMS = clientSetting.timeOutByMS;

                        //初始化后,不可更改!
                        bufferManager = new BufferManager(clientSetting.bufferSize * clientSetting.opsToPreAllocate * clientSetting.numberOfSaeaForRecSend, clientSetting.bufferSize * clientSetting.opsToPreAllocate);
                        bufferManager.InitBuffer();

                        //用于负责建立连接的saea,无关buffermanager,10个足够!这部分实际在ClientSocketProcessor中可以动态增加
                        //poolOfConnectEventArgs = new SocketAsyncEventArgPool(clientSetting.maxSimultaneousConnectOps);
                        poolOfConnectEventArgs = new SocketAsyncEventArgPool();

                        //用于负责在建立好的连接上传输数据,涉及buffermanager,目前测试100~200个足够!这部分目前不支持动态增加!
                        //因其buffermanager是事先分配好的一大块连续的固定内存区域,强烈建议不再更改,需要做好的就是事先的大小评估。
                        //poolOfRecSendEventArgs = new SocketAsyncEventArgPool(clientSetting.numberOfSaeaForRecSend);
                        poolOfRecSendEventArgs = new SocketAsyncEventArgPool();

                        //实际负责处理相关传输数据的关键核心类
                        processor = new ClientSocketProcessor(poolOfConnectEventArgs, poolOfRecSendEventArgs, clientSetting.numberOfSaeaForRecSend, clientSetting.bufferSize, clientSetting.numberOfMessagesPerConnection, clientSetting.receivePrefixLength, clientSetting.useKeepAlive, "bizclient");

                        //由于不涉及buffermanager,可动态增长
                        for (int i = 0; i < clientSetting.maxSimultaneousConnectOps; i++)
                        {
                            SocketAsyncEventArgs connectEventArg = new SocketAsyncEventArgs();
                            connectEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(processor.IO_Completed);

                            //关键负责标识saea和更关键的传输待发送的数据给传输用的saea。
                            ConnectOpUserToken theConnectingToken = new ConnectOpUserToken();
                            connectEventArg.UserToken = theConnectingToken;

                            poolOfConnectEventArgs.Push(connectEventArg);
                        }

                        //涉及buffermanager,不可动态增长,需事先评估即可,负责实际的数据传输
                        for (int i = 0; i < clientSetting.numberOfSaeaForRecSend; i++)
                        {
                            SocketAsyncEventArgs eventArgObjectForPool = new SocketAsyncEventArgs();

                            //事先为每个saea分配固定不变的内存位置!
                            bufferManager.SetBuffer(eventArgObjectForPool);

                            eventArgObjectForPool.Completed += new EventHandler <SocketAsyncEventArgs>(processor.IO_Completed);

                            ClientUserToken receiveSendToken = new ClientUserToken(eventArgObjectForPool.Offset, eventArgObjectForPool.Offset + clientSetting.bufferSize, clientSetting.receivePrefixLength, clientSetting.sendPrefixLength);

                            //用于传递待发送的数据,一旦完成发送必须重新new一个。
                            receiveSendToken.CreateNewSendDataHolder();
                            eventArgObjectForPool.UserToken = receiveSendToken;

                            poolOfRecSendEventArgs.Push(eventArgObjectForPool);
                        }

                        bufferManager.SetInitComplete();

                        sw.Stop();

                        LogManager.Log(string.Format("SocketClient Init by FirstInvoke Completed! ConsumeTime:{0} ms", sw.ElapsedMilliseconds));

                        isInit = true;
                    }
                }
            }
        }