예제 #1
0
 private Action GetProcessCustomerAction(Cashier cashier, CancellationToken token)
 {
     return(() =>
     {
         try
         {
             var customer = customersQueue.DequeueCustomer(); // blocking operation!
             var rnd = new Random();
             var processDurationInSeconds = rnd.Next(minCashierProcessingTime, maxCashierProcessingTime + 1);
             cashier.ProcessCustomer(customer, processDurationInSeconds); // blocking operation!
             logger.Info($"{cashier.Name} finished processing customer at: {customer.Finished}. Number of waiting customers: {customersQueue.GetCustomersCount()}");
         }
         catch (Exception e)
         {
             logger.Error($"Error in {cashier.Name} work: {e}");
         }
         finally
         {
             // I issue a new task instaed of just calling this Action recursively, beacuse it will cause
             // the call stack to chain and eventually to cause an out of memory error.
             // The child task is, by deafult, detached from its parent task and therefore will not chain a call stack.
             if (!token.IsCancellationRequested)
             {
                 taskFactory.StartNew(GetProcessCustomerAction(cashier, token), token);
             }
             else
             {
                 logger.Info($"{cashier.Name} work was cancelled. Stopping.");
             }
         }
     });
 }
예제 #2
0
        private void ProcessSingleCustomer()
        {
            var customer = customersQueue.DequeueCustomer(); // blocking operation
            var rnd      = new Random();
            var processDurationInSeconds = rnd.Next(minCashierProcessingTime, maxCashierProcessingTime + 1);

            taskFactory.StartNew(() =>
            {
                var cashier = new Cashier($"Cashier-{Thread.CurrentThread.ManagedThreadId}", sleepService);

                try
                {
                    cashier.ProcessCustomer(customer, processDurationInSeconds); // blocking operation!
                    logger.Info($"{cashier.Name} finished processing customer at: {customer.Finished}. Number of waiting customers: {customersQueue.GetCustomersCount()}");
                }
                catch (Exception e)
                {
                    logger.Error($"Error in {cashier.Name} work: {e}");
                }
                finally
                {
                    maxCashiersSemaphore.Release();
                }
            });
        }