private bool HandshakeServer(SymServer symServer)
        {
            try
            {
                if (symServer == null)
                {
                    return(false);
                }

                symServer.IsInUse = true;

                //var client = _symConnectionList[symServer.Id];
                var client = _symConnectionList.Find(symConn => symConn.Id == symServer.Id).TcpClient;

                // open if not already open
                if (!client.Connected)
                {
                    client.Connect(symServer.Host, symServer.Port);
                }

                // send/rcv buffers
                var req  = Encoding.ASCII.GetBytes("HANDSHAKE\n");
                var resp = new byte[_maxbuffersize];

                // send handshake
                var socket = client.Client;
                socket.Send(req);

                // get & validate response
                socket.Receive(resp);
                var handshakeResponse = Encoding.ASCII.GetString(resp).Replace("\0", "").Replace("\n", "").Trim(); //trim nulls and control chars;

                if (handshakeResponse.StartsWith("RSHANDSHAKE"))
                {
                    // good response
                    symServer.IsInUse = false;
                    return(true);
                }

                // bad response; leave host out of pool
                return(false);
            }
            catch (SocketException s)
            {
                if (s.ErrorCode == 10061) // refused; connection not open or in use
                {
                    // take server out of rotation
                    symServer.IsFaulted = true;
                    return(false);
                }

                // take server out of rotation
                symServer.IsFaulted = true;
                return(false);
            }
        }
        /// <summary>
        /// Asyncronously fetch our next symServer from the list
        /// </summary>
        /// <returns></returns>
        private async Task <SymServer> AcquireNextHost()
        {
            int attempts = 0;
            //set a task completion source and a timer, attempt to re-acquire our socket every
            TaskCompletionSource <SymServer> tcs = null;
            SymServer acquiredServer             = null;
            //set timer for retry interval on send
            var t = new System.Timers.Timer()
            {
                AutoReset = true, Enabled = true, Interval = _retryInterval
            };

            //create task completion source loop
            tcs        = new TaskCompletionSource <SymServer>(t);
            t.Elapsed += (sender, e) =>
            {
                var senderTimer = sender as System.Timers.Timer;
                lock (_acquireSocketLock)
                {
                    acquiredServer = GetNextHost();
                }
                attempts++;

                if (acquiredServer != null || attempts > _maxRetries)
                {
                    senderTimer.Close();
                    if (!tcs.TrySetResult(acquiredServer))
                    {
                        System.Diagnostics.Debug.WriteLine("Failed to set result for host acquisition");
                    }
                }
            };
            //activate our timer
            t.Start();
            //await our task result
            return(await tcs.Task);
        }
 private void UnlockHost(SymServer host)
 {
     // unlock server
     host.IsInUse = false;
 }