Friday, March 8, 2013

Allow an Action to be executed only nn number of times.

"Barrier" is not quite the correct word.. But this does fit my needs.
        public static Action ActionBarrier( this Action action, long remainingCallsAllowed = 1 ) {
            var context = new ContextCallOnlyXTimes( remainingCallsAllowed );
            return () => {
                if ( Interlocked.Decrement( ref context.CallsAllowed ) >= 0 ) {
                    action();
                }
            };
        }

        public class ContextCallOnlyXTimes {
            public ContextCallOnlyXTimes( long times ) {
                if ( times <= 0 ) { times = 0; }
                this.CallsAllowed = times;
            }
            public long CallsAllowed;
        }

Example:

        private static void ActionBarrierExample() {

            var foo = new Action( Foo );
            var fooWithBarrier = foo.ActionBarrier( remainingCallsAllowed: 1 );
            fooWithBarrier();
            fooWithBarrier();
            fooWithBarrier();

            var barWithBarrier = ThreadingExtensions.ActionBarrier( action: Bar, remainingCallsAllowed: 2 );
            var bob1 = new Thread( () => barWithBarrier() );
            var bob2 = new Thread( () => barWithBarrier() );
            var bob3 = new Thread( () => barWithBarrier() );
            var bob4 = new Thread( () => barWithBarrier() );

            bob1.Start();
            bob2.Start();
            bob3.Start();
            bob4.Start();

            bob1.Join();
            bob2.Join();
            bob3.Join();
            bob4.Join();

            Console.WriteLine( "enter return" );
            Console.ReadLine();
        }

No comments: