Beispiel #1
0
        /// <summary>
        /// Select an applicable function without executing it
        /// </summary>
        /// <param name="context">gate context</param>
        /// <param name="mode">mode to run the gated code in</param>
        /// <param name="functions">array of gated functions</param>
        /// <param name="keepContext">controls whether async operation should keep the synchronization context</param>
        /// <remarks>
        /// keep context should be set to true in code which is async end to end,
        /// and false in other cases to avoid deadlocking
        /// </remarks>
        /// <returns>a function to perform, never null</returns>
        public static Func <T, Task <T> > SelectFunction <T>(this IGateContext context, GatedCode.Modes mode, GatedAsyncFunc <T, T>[] functions, bool keepContext)
        {
            Tuple <GatedAsyncFunc <T, T>, IGate[]> action = SelectCode(context, null, functions);

            if (action != null && action.Item1 != null)
            {
                return(async t =>
                {
                    context.EnterScopes(mode, action.Item2);

                    try
                    {
                        if (action.Item1.Func != null)
                        {
                            return await action.Item1.Func(t).ConfigureAwait(keepContext);
                        }
                    }
                    finally
                    {
                        context.ExitScopes(mode, action.Item2);
                    }

                    return t;
                });
            }

            return(Task.FromResult);
        }
Beispiel #2
0
        /// <summary>
        /// Select an applicable function without executing it
        /// </summary>
        /// <typeparam name="T">Generic type</typeparam>
        /// <param name="context">gate context</param>
        /// <param name="mode">mode to run the gated code in</param>
        /// <param name="conditionalPredicate">The conditional predicate.</param>
        /// <param name="functions">array of gated functions</param>
        /// <param name="keepContext">controls whether async operation should keep the synchronization context</param>
        /// <remarks>
        /// keep context should be set to true in code which is async end to end,
        /// and false in other cases to avoid deadlocking
        /// </remarks>
        /// <returns>a function to perform, never null</returns>
        public static Func <Task <T> > SelectFunction <T>(this IGateContext context, GatedCode.Modes mode, Func <bool> conditionalPredicate,
                                                          GatedAsyncFunc <T>[] functions, bool keepContext)
        {
            Tuple <GatedAsyncFunc <T>, IGate[]> action = SelectCode(context, conditionalPredicate, functions);

            if (action?.Item1 == null)
            {
                return(() => Task.FromResult(default(T)));
            }

            return(async() =>
            {
                context.EnterScopes(mode, action.Item2);

                try
                {
                    if (action.Item1.Func != null)
                    {
                        return await action.Item1.Func().ConfigureAwait(keepContext);
                    }
                }
                finally
                {
                    context.ExitScopes(mode, action.Item2);
                }

                return default(T);
            });
        }
Beispiel #3
0
        /// <summary>
        /// Select an applicable function without executing it
        /// </summary>
        /// <param name="context">gate context</param>
        /// <param name="mode">mode to run the gated code in</param>
        /// <param name="functions">array of gated functions</param>
        /// <returns>a function to perform, never null</returns>
        public static Func <T, T> SelectFunction <T>(this IGateContext context, GatedCode.Modes mode, params GatedFunc <T, T>[] functions)
        {
            Tuple <GatedFunc <T, T>, IGate[]> action = SelectCode(context, null, functions);

            if (action != null && action.Item1 != null)
            {
                return(new Func <T, T>(
                           (t) =>
                {
                    context.EnterScopes(mode, action.Item2);

                    try
                    {
                        if (action.Item1.Func != null)
                        {
                            return action.Item1.Func(t);
                        }
                    }
                    finally
                    {
                        context.ExitScopes(mode, action.Item2);
                    }

                    return t;
                }));
            }

            return(new Func <T, T>((t) => t));
        }
Beispiel #4
0
        /// <summary>
        /// Select an applicable function without executing it
        /// </summary>
        /// <typeparam name="T">Generic type</typeparam>
        /// <param name="context">gate context</param>
        /// <param name="mode">mode to run the gated code in</param>
        /// <param name="conditionalPredicate">The conditional predicate.</param>
        /// <param name="functions">array of gated functions</param>
        /// <returns>a function to perform, never null</returns>
        public static Func <T> SelectFunction <T>(this IGateContext context, GatedCode.Modes mode, Func <bool> conditionalPredicate,
                                                  params GatedFunc <T>[] functions)
        {
            Tuple <GatedFunc <T>, IGate[]> action = SelectCode(context, conditionalPredicate, functions);

            if (action != null && action.Item1 != null)
            {
                return(new Func <T>(
                           () =>
                {
                    context.EnterScopes(mode, action.Item2);

                    try
                    {
                        if (action.Item1.Func != null)
                        {
                            return action.Item1.Func();
                        }
                    }
                    finally
                    {
                        context.ExitScopes(mode, action.Item2);
                    }
                    return default(T);
                }));
            }

            return(new Func <T>(() => default(T)));
        }
Beispiel #5
0
        /// <summary>
        /// Select an applicable action without executing it
        /// </summary>
        /// <param name="context">gate context</param>
        /// <param name="mode">mode to run the gated code in</param>
        /// <param name="conditionalPredicate">The conditional predicate.</param>
        /// <param name="actions">array of gated actions</param>
        /// <param name="keepContext">controls whether async operation should keep the synchronization context</param>
        /// <remarks>
        /// keep context should be set to true in code which is async end to end,
        /// and false in other cases to avoid deadlocking
        /// </remarks>
        /// <returns>an action to perform, never null</returns>
        public static Func <Task> SelectAction(this IGateContext context, GatedCode.Modes mode, Func <bool> conditionalPredicate, GatedAsyncAction[] actions, bool keepContext = false)
        {
            Tuple <GatedAsyncAction, IGate[]> action = SelectCode(context, conditionalPredicate, actions);

            if (action?.Item1 == null)
            {
                return(s_noOpAction);
            }

            return(async() =>
            {
                context.EnterScopes(mode, action.Item2);

                try
                {
                    if (action.Item1?.Action != null)
                    {
                        await action.Item1.Action().ConfigureAwait(keepContext);
                    }
                }
                finally
                {
                    context.ExitScopes(mode, action.Item2);
                }
            });
        }
Beispiel #6
0
        /// <summary>
        /// Select an applicable action without executing it
        /// </summary>
        /// <param name="context">gate context</param>
        /// <param name="mode">mode to run the gated code in</param>
        /// <param name="conditionalPredicate">The conditional predicate.</param>
        /// <param name="actions">array of gated actions</param>
        /// <returns>an action to perform, never null</returns>
        public static Action SelectAction(this IGateContext context, GatedCode.Modes mode, Func <bool> conditionalPredicate, params GatedAction[] actions)
        {
            Tuple <GatedAction, IGate[]> action = SelectCode(context, conditionalPredicate, actions);

            if (action != null && action.Item1 != null)
            {
                return(new Action(
                           () =>
                {
                    context.EnterScopes(mode, action.Item2);

                    try
                    {
                        action.Item1.Action?.Invoke();
                    }
                    finally
                    {
                        context.ExitScopes(mode, action.Item2);
                    }
                }));
            }

            return(new Action(() => { }));
        }