/// <summary>
        /// Execute func for each int from and including fromInclusive and up to but not including toExclusive.
        /// Funcs will execute on distributed node proxies based on subscription rate.
        /// </summary>
        /// <typeparam name="TReturn">The return type of func.</typeparam>
        /// <param name="fromInclusive">The starting index value.</param>
        /// <param name="toExclusive">The ending index value plus one.</param>
        /// <param name="func">The Func that returns TReturn and takes the int index value, the DistributedLoopState of TReturn and TInterface as inputs.</param>
        /// <returns>DistributedLoopResult of TReturn.</returns>
        public DistributedLoopResult <TReturn> For <TReturn>(int fromInclusive, int toExclusive, Func <int, DistributedLoopState <TReturn>, TInterface, TReturn> func)
        {
            if (toExclusive <= fromInclusive)
            {
                return(new DistributedLoopResult <TReturn>());
            }
            var state = new DistributedLoopState <TReturn>();

            for (int index = fromInclusive; index < toExclusive; index++)
            {
                if (!state.ContinueProcessing)
                {
                    break;
                }
                var        proxyIndex = GetNextBalancedProxyIndex();
                TInterface t          = _intercepts[proxyIndex];
                int        locIndex   = index;
                state.Tasks.Add(Task.Factory.StartNew(() =>
                {
                    try
                    {
                        if (state.ContinueProcessing)
                        {
                            var funcResult = func(locIndex, state, t);
                            state.ReturnValues.Add(funcResult);
                        }
                    }
                    catch (Exception e)
                    {
                        var err = new DistributedExceptionInfo
                        {
                            Exception = e,
                            EndPoint  = _interceptEndPoints[proxyIndex],
                            Index     = locIndex,
                            Source    = null,
                            TimeStamp = DateTime.Now
                        };
                        state.ExceptionInfos.Add(err);
                    }
                }, TaskCreationOptions.LongRunning));
            }
            Task.WaitAll(state.Tasks.ToArray());
            var result = new DistributedLoopResult <TReturn>()
            {
                Exceptions     = state.ExceptionInfos.ToArray(),
                Results        = state.ReturnValues.ToArray(),
                BreakIteration = state.BreakIteration
            };

            return(result);
        }
        /// <summary>
        /// Execute func once per server node. Used most commonly to set the state of the singleton of TInterface hosted on the remote node.
        /// </summary>
        /// <typeparam name="TReturn">The return type of the Func passed into this method.</typeparam>
        /// <typeparam name="TSource">The input source type for each action.</typeparam>
        /// <param name="source">The input source object to be used in each execution of action on each server node proxy.</param>
        /// <param name="func">The Func that takes the node index, source object, DistributedLoopState of TReturn and the TInterface proxy and returns the TReturn object.</param>
        /// <returns>Returns DistributedLoopResult of type TReturn, the return value of func.</returns>
        public DistributedLoopResult <TReturn> OncePerNode <TReturn, TSource>(TSource source, Func <int, TSource, DistributedLoopState <TReturn>, TInterface, TReturn> func)
        {
            var state = new DistributedLoopState <TReturn>();

            for (int i = 0; i < _proxiesOnePerNode.Length; i++)
            {
                if (!state.ContinueProcessing)
                {
                    break;
                }
                TSource    locSource = source;
                TInterface t         = _proxiesOnePerNode[i];
                var        locIndex  = i;
                state.Tasks.Add(Task.Factory.StartNew(() =>
                {
                    try
                    {
                        if (state.ContinueProcessing)
                        {
                            var funcResult = func(locIndex, locSource, state, t);
                            state.ReturnValues.Add(funcResult);
                        }
                    }
                    catch (Exception e)
                    {
                        var err = new DistributedExceptionInfo
                        {
                            Exception = e,
                            EndPoint  = _servers[locIndex],
                            Index     = locIndex,
                            Source    = locSource,
                            TimeStamp = DateTime.Now
                        };
                        state.ExceptionInfos.Add(err);
                    }
                }, TaskCreationOptions.LongRunning));
            }
            Task.WaitAll(state.Tasks.ToArray());
            var result = new DistributedLoopResult <TReturn>()
            {
                Exceptions     = state.ExceptionInfos.ToArray(),
                Results        = state.ReturnValues.ToArray(),
                BreakIteration = state.BreakIteration
            };

            return(result);
        }
 internal DistributedLoopResult()
 {
     Exceptions = new DistributedExceptionInfo[0];
 }