/// <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); }