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