예제 #1
0
        private void FinishRemainingCustomers()
        {
            logger.Info("Store was closed. Finishing with the last remaining customers.");

            while (customersQueue.GetCustomersCount() > 0)
            {
                maxCashiersSemaphore.Wait(); // blocking operation
                ProcessSingleCustomer();
            }
        }
예제 #2
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.");
             }
         }
     });
 }