コード例 #1
0
        // This project demonstrates Redis as a Distributed Lock Manager combined with
        // Aspect Oriented Programming to create a 'MethodMutex' aspect. When a method
        // is decorated with this aspect, it effectively becomes single "threaded"
        // across all running instances, even if they are in different processes or on
        // different planets. Additionally, code calling the decorated method receives
        // immediate feedback and can determine whether to retry, continue, or take
        // any other course of action.
        //
        // To see it in action, build the project then find the executable in your
        // output/bin folder and launch multiple instances. Be sure to update the
        // app.config file with the connection info for your Redis server!


        public static void Main()
        {
            WorkerInstance worker2 = new WorkerInstance();

            while (true)
            {
                Console.WriteLine(worker2.DoWork());
                System.Threading.Thread.Sleep(1000);
            }


            Process thisInstance = Process.GetCurrentProcess();

            Process[] allInstances = Process.GetProcessesByName(thisInstance.ProcessName);
            Thread.Sleep(200);  // helps to randomize which instance gets the mutex first

            while (allInstances.Length == 1)
            {
                Console.Clear();
                Console.WriteLine("Redis Distributed Locking Example\r\n");
                Console.WriteLine("Launch a 2nd instance of this app to start...");
                Thread.Sleep(400);
                allInstances = Process.GetProcessesByName(thisInstance.ProcessName);
            }
            Console.Clear();
            Console.WriteLine("Redis Distributed Locking Example\r\n");
            Console.WriteLine("Attempting to do work on PID {0}...\r\n", thisInstance.Id);

            WorkerInstance worker      = new WorkerInstance();
            bool           gotWorkDone = worker.DoWork();

            if (!gotWorkDone)
            {
                Console.WriteLine("{0:T} - Method was locked, waiting...", DateTime.Now);
                // whether to retry or continue depends on your specific scenario
                // for demo, we'll retry. In cases where workers might receive
                // duplicate payloads near-instantaneously and only one should
                // succeed, you might just choose to continue.

                Stopwatch time = Stopwatch.StartNew();
                do
                {
                    Thread.Sleep(500);
                    gotWorkDone = worker.DoWork();
                    Console.WriteLine("gotWorkDone: " + gotWorkDone);
                } while (!gotWorkDone && time.Elapsed < TimeSpan.FromMinutes(1));
                time.Stop();

                if (!gotWorkDone)
                {
                    Console.WriteLine("Timed out after 1 minute...");
                }
            }

            Console.WriteLine("Press any key to quit, 'Q' to quit all...");
            var ck = Console.ReadKey();

            if (ck.KeyChar == 'Q')
            {
                allInstances = Process.GetProcessesByName(thisInstance.ProcessName);
                foreach (var app in allInstances)
                {
                    app.CloseMainWindow();
                }
            }
        }
コード例 #2
0
        // This project demonstrates Redis as a Distributed Lock Manager combined with
        // Aspect Oriented Programming to create a 'MethodMutex' aspect. When a method
        // is decorated with this aspect, it effectively becomes single "threaded"
        // across all running instances, even if they are in different processes or on
        // different planets. Additionally, code calling the decorated method receives
        // immediate feedback and can determine whether to retry, continue, or take
        // any other course of action.
        //
        // To see it in action, build the project then find the executable in your
        // output/bin folder and launch multiple instances. Be sure to update the
        // app.config file with the connection info for your Redis server!
        public static void Main()
        {
            WorkerInstance worker2 = new WorkerInstance();

            while (true)
            {
                Console.WriteLine(worker2.DoWork());
                System.Threading.Thread.Sleep(1000);
            }

            Process thisInstance = Process.GetCurrentProcess();
            Process[] allInstances = Process.GetProcessesByName(thisInstance.ProcessName);
            Thread.Sleep(200);  // helps to randomize which instance gets the mutex first

            while (allInstances.Length == 1)
            {
                Console.Clear();
                Console.WriteLine("Redis Distributed Locking Example\r\n");
                Console.WriteLine("Launch a 2nd instance of this app to start...");
                Thread.Sleep(400);
                allInstances = Process.GetProcessesByName(thisInstance.ProcessName);
            }
            Console.Clear();
            Console.WriteLine("Redis Distributed Locking Example\r\n");
            Console.WriteLine("Attempting to do work on PID {0}...\r\n", thisInstance.Id);

            WorkerInstance worker = new WorkerInstance();
            bool gotWorkDone = worker.DoWork();
            if (!gotWorkDone)
            {
                Console.WriteLine("{0:T} - Method was locked, waiting...", DateTime.Now);
                // whether to retry or continue depends on your specific scenario
                // for demo, we'll retry. In cases where workers might receive
                // duplicate payloads near-instantaneously and only one should
                // succeed, you might just choose to continue.

                Stopwatch time = Stopwatch.StartNew();
                do
                {
                    Thread.Sleep(500);
                    gotWorkDone = worker.DoWork();
                    Console.WriteLine("gotWorkDone: " + gotWorkDone);
                } while (!gotWorkDone && time.Elapsed < TimeSpan.FromMinutes(1));
                time.Stop();

                if (!gotWorkDone)
                {
                    Console.WriteLine("Timed out after 1 minute...");
                }
            }

            Console.WriteLine("Press any key to quit, 'Q' to quit all...");
            var ck = Console.ReadKey();
            if (ck.KeyChar == 'Q')
            {
                allInstances = Process.GetProcessesByName(thisInstance.ProcessName);
                foreach (var app in allInstances)
                {
                    app.CloseMainWindow();
                }
            }
        }