public IAsyncResult BeginExecOnNearServer <S, R>(IAPMServices <S, R> s, Uri[] servers, S service,
                                                         AsyncCallback ac, object state)
        {
            GenericAsyncResult <R> gar = new GenericAsyncResult <R>(ac, state, false);
            int got = 0, failures = 0;

            for (int i = 0; i < servers.Length; i++)
            {
                s.BeginPingServer(servers[i], onPingServer, null);
            }
            void onPingServer(IAsyncResult ar)
            {
                try
                {
                    Uri uri = s.EndPingServer(ar);
                    if (Interlocked.Exchange(ref got, 1) == 0)
                    {
                        s.BeginExecService(uri, service, onExecService, null);
                    }
                }
                catch (Exception ex)
                {
                    if (Interlocked.Increment(ref failures) == servers.Length)
                    {
                        gar.SetException(ex);
                    }
                }
            }

            void onExecService(IAsyncResult ar)
            {
                try
                {
                    gar.SetResult(s.EndExecService(ar));
                }
                catch (Exception ex)
                {
                    gar.SetException(ex);
                }
            }

            return(gar);
        }