public OrderProcessing(OrderClass order) { this.order = order; lock (order_num) { order_num = (int)order_num + 1; local_order_num = (int)order_num; } }
/* * EVENT HANDLER (this will be used to actually process our purchase order.) * It receives the orders from the MultiCellBuffer (MCB). For each order, a new thread is started * (resulting in multiple threads for processing multiple orders) from OrderProcessing class in * order to process the purchase order based on the current price. */ public void processPO() { OrderClass purchaseOrder = Program.MCB.getOneCell(); // retrieves our PO from our MCB // creates a new thread for each new order from the OrderProcessing class in order to process our purchase order. Thread processPO_Thread = new Thread(() => OrderProcessing.orderProcess(purchaseOrder, get_ticketPrice())); processPO_Thread.Start(); }
public static string Encode(OrderClass o) { XmlSerializer serialize = new XmlSerializer(o.GetType()); using (StringWriter swriter = new StringWriter()) { serialize.Serialize(swriter, o); string encoded = swriter.ToString(); return(encoded); } }
// Confirms a book order from the publisher public static void Confirmation(OrderClass order) { lock (COUNT_OBJECT_LOCK) { Console.WriteLine("\n\n\t Order by " + order.SenderId + " has been received by " + order.ReceiverId + " and confirmed! The details are: "); Console.WriteLine("\t Unit price: $" + order.Unit_Price.ToString("0.00")); Console.WriteLine("\t Amount: " + order.Amount.ToString()); Console.WriteLine("\t CC number: " + order.CardNo.ToString() + "\n\n"); count_confirmations++; } }
// Function for starting the threads in Program public void PublisherFunction() { Console.WriteLine(Thread.CurrentThread.Name + " has opened!"); while (p < 20) { Thread.Sleep(random.Next(1500, 4000)); string s = buffer.ReadFromBuffer(); // Gets order string if (s != null) { // Determines new price using the PriceModel new_price = PricingModel(s); // Lower new price means p is increased and priceCut event is exectuted // Print new price if (new_price < past_price) { p++; Console.Write(">> Price decreased for Publisher # " + publisherId + " from $" + past_price.ToString("0.00") + " to $" + new_price.ToString("0.00") + "\n"); past_price = new_price; if (priceCut != null) //Added null check { priceCut(publisherId, new_price); } } // Print new increased price else if (new_price > past_price) { Console.Write(">> Price increased for Publisher # " + publisherId + " from $" + past_price.ToString("0.00") + " to $" + new_price.ToString("0.00") + "\n"); past_price = new_price; } // If price stays the same, print nothing else { past_price = new_price; } // starts OrderProcessing thread OrderClass order = Cipher.decoder(s); order.Unit_Price = new_price; //I changed the reciever id to just the name of the thread order.ReceiverId = Thread.CurrentThread.Name.ToString(); Thread t = new Thread(() => Project2.OrderProcessingThread.OPT(order)); t.Start(); } } Console.WriteLine(Thread.CurrentThread.Name + " has closed!"); Program.setRunning(publisherId, false); }
public static void OPT(OrderClass order) { // Checks whether card number is valid if (order.CardNo < 1000 && order.CardNo > 100) { double taxed = order.Unit_Price * tax; double total_amount = (taxed + order.Unit_Price) * order.Amount; Console.WriteLine("Order: " + order.SenderId + "; " + order.ReceiverId + "; totaled $" + total_amount.ToString("0.00")); // Sends confirmation to bookstore Project2.BookStore.Confirmation(order); } }
// Created by Jacqueline Fonseca public static OrderClass decoder(string orderString) { OrderClass orderObject = new OrderClass(); string[] parsed = orderString.Split(','); orderObject.SenderId = parsed[0]; orderObject.CardNo = Convert.ToInt32(parsed[1]); orderObject.ReceiverId = parsed[2]; orderObject.Amount = Convert.ToInt32(parsed[3]); orderObject.Unit_Price = Convert.ToDouble(parsed[4]); return(orderObject); }
//Create bulk order when final price of books is less than 100 public void create_bulk_order(string PublisherId) { OrderClass order = new OrderClass(); //create an order object. Random randm = new Random(); bulk_books_order = random.Next(11, 25); order.No_of_books = bulk_books_order; order.BookstoreID = Thread.CurrentThread.Name; order.CardNo = cardnos[Convert.ToInt32(order.BookstoreID)]; order.PublisherId = PublisherId; booksneeded = false; //after you're done creating bulk order, set it to false to wait for next price cut. string order_string = Encoder.Encode(order); Program.buffer.setOneCell(order_string); }
/* * Our getOneCell method is used to read data (purchase orders) from our cells * A semaphore is used to block our thread until a signal is received to read data. * We lock our list of OrderClass objects (purchase orders) to manage read/write permissions * and we also implement additional monitors to prevent trying to read from an empty MCB. */ public OrderClass getOneCell() { OrderClass PO = null; get_pool.WaitOne(); // rw_pool.WaitOne(); // functionally equivalent to Monitor.Enter/Monitor.Exit lock (purchaseOrders) { // once our cells are empty, block threads from trying to get POs that do not exist if (nCount == 0) { Monitor.Wait(purchaseOrders); } // for loop to read our purchase order from each cell in our list for (int i = 0; i < n; i++) { if (purchaseOrders[i] != null) // makes sure there is something to read a each cell { PO = purchaseOrders[i]; // Copy our PO details purchaseOrders.RemoveAt(i); // Remove PO from MCB nCount--; // Decrement our count i = n; // terminate loop to ensure we only get 1 cell } } /* * for(int i = 0; i < n; i++) * { * if(purchaseOrders[i] != null) * { * PO = purchaseOrders[i]; * purchaseOrders[i] = null; // reset this cell to null * nCount--; // decrement the to signify a cell is available for a new ticket PO * i = n; // exit the loop in order to prevent setting all cells to null * } * } * */ get_pool.Release(); // rw_pool.Release(); Monitor.Pulse(purchaseOrders); } return(PO); }
// Created by Matthew Lillie public static string encoder(OrderClass orderObject) { string encodedString = ""; encodedString += orderObject.SenderId; encodedString += ","; encodedString += orderObject.CardNo.ToString(); encodedString += ","; encodedString += orderObject.ReceiverId; encodedString += ","; encodedString += orderObject.Amount.ToString(); encodedString += ","; encodedString += orderObject.Unit_Price.ToString(); return(encodedString); }
/* * Method used to process the ticket agencies order if the cardNo being used is valid. */ public static void orderProcess(OrderClass order, double price) { // if/else to handle invalid cardNo if (!isValid(order.get_cardNo())) { Console.WriteLine("Please check your card number and re-enter, it is invalid: " + order.get_cardNo()); return; } else { double cost = 0.0; cost = (price * order.get_amount()); // insert processPO event here PO_Processed(order.get_senderId(), order.get_cardNo(), order.get_amount(), cost); // emit our processPO event } }
/* * The higherTicketPO method is used to create a purchase order based on the pricing event. * This specifically handles when the price increase, so that the ticket agency demand for * amount of tickets will go down to ensure they order more tickets when the price is cheaper. */ private void higherTicketPO(string threadID, double price) { int cardNo = rand.Next(4000, 5000); // generate a random number to signify our CC #. int amount = rand.Next(10, 40); // generate a lower need for tickets when price is higher // instantiate and OrderClass object to hold our ticket purchase order OrderClass purchaseOrder = new OrderClass(threadID, cardNo, amount, price); // implementation of timestamp before sending purchase order to MCB. Console.WriteLine("Ticket Agency {0} has a new purchase order for {1} tickets at {2}.", threadID, amount, DateTime.Now.ToString("hh:mm:ss")); Program.MCB.setOneCell(purchaseOrder); // place purchase order into MCB newPO(); // emits event }
//Create Normal order when final price of books is greater than 100 public void create_normal_order(String PublisherId) { OrderClass order = new OrderClass(); Random randm = new Random(); normal_books_order = random.Next(1, 10); order.No_of_books = normal_books_order; order.BookstoreID = Thread.CurrentThread.Name; order.CardNo = cardnos[Convert.ToInt32(order.BookstoreID)]; order.BookstoreID = Thread.CurrentThread.Name; order.PublisherId = PublisherId; booksneeded = false; string order_string = Encoder.Encode(order); Program.buffer.setOneCell(order_string); }
/* * Our setOneCell method is used to write data to our cells * A semaphore is used to manage the availability of cells and a lock is placed on * our list of OrderClass objects (purchase orders) to manage read/write permissions * and we also implement additional monitors to prevent writing to a full MCB. */ public void setOneCell(OrderClass PO) { set_pool.WaitOne(); // requesting a write resource/enter the set_pool semaphore // rw_pool.WaitOne(); // functionally equivalent to Monitor.Enter/Monitor.Exit lock (purchaseOrders) { if (nCount == n) { // block other threads from trying to send a new PO to MCB while PO count = 3 Monitor.Wait(purchaseOrders); } // for loop to insert our purchase order into the next available cell in our list for (int i = 0; i < n; i++) { // need to check to see if a PO already exists //if (purchaseOrders.ElementAt(i).Equals(PO)) //if(purchaseOrders.ElementAt(i) == null) { purchaseOrders.Insert(i, PO); nCount++; // increment our nCount i = n; // exiting loop once PO is added to avoid duplicates } } /* * for(int i = 0; i < n; i++) * { * * if(purchaseOrders[i] == null) * { * * purchaseOrders[i] = PO; * nCount++; // increment cell count to show one less cell is available * i = n; // set i = n to exit loop and prevent duplicate POs * * } * } */ set_pool.Release(); // release the semaphore once // rw_pool.Release(); Monitor.Pulse(purchaseOrders); // send notification to our thread that cell is available } }
//Printing Order Confirmation public void ProcessOrder(OrderClass o, double currentPrice) { if (o.PublisherId == Thread.CurrentThread.Name) { //need to add logic to this for processing order Console.WriteLine("Order for bookstore {0} received", Thread.CurrentThread.Name); OrderProcessing orderProcessing = new OrderProcessing(o); o.Current_Price_order = currentPrice; Thread p_thread = new Thread(new ThreadStart(orderProcessing.processOrder)); processingThreads.Add(p_thread); p_thread.Name = "p_thread " + Thread.CurrentThread.Name; p_thread.Start(); } else { Console.WriteLine("This order is not for Publisher {0} " + Thread.CurrentThread.Name); } }
/// <summary> /// Initializes a new instance of the <see cref="OrderProcessing"/> class. /// </summary> /// <param name="order">The order.</param> /// <param name="price">The price.</param> public OrderProcessing(OrderClass order, double price) { OrderObject = order; chickenPrice = price; }
/// <summary> /// Runs the store to send orders to the chicken farm. /// </summary> public void RunStore() { var orderTimes = new List<long>(); var baseChickens = Thread.CurrentThread.ManagedThreadId * 23; var chickenDemand = Thread.CurrentThread.ManagedThreadId * 7 / 2; // Loop until stop is requested while (!token.IsCancellationRequested) { WaitHandle.WaitAny(new[] { priceCutManualResetEvent, token.WaitHandle }); if (!token.IsCancellationRequested) //did cancellation wake us? { int numChickens; lock (syncRoot) { // Determine what to order based on price and demand. numChickens = baseChickens - chickenDemand * (int)(chickenPrice); } // Put in order for chickens if (numChickens > 0) { int ccNumber = Math.Min(7000, 5000 + Thread.CurrentThread.ManagedThreadId + numChickens); var OrderObject = new OrderClass { Amount = numChickens, SenderId = Thread.CurrentThread.Name, CardNo = ccNumber }; //sends order to encoder string encoded = OrderObject.Encode(); timeSent = DateTime.UtcNow; //send encoded string to free cell in multiCellBuffer var cell = new MultiCellBuffer(token); try { cell.SetOneCell(encoded); // Wait for order confirmation var eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Thread.CurrentThread.Name); WaitHandle.WaitAny(new[] { eventWaitHandle, token.WaitHandle }); DateTime timeReceive = DateTime.UtcNow; TimeSpan elapsedTime = timeReceive - timeSent; Console.WriteLine("The order for {0} took {1} ms.", Thread.CurrentThread.Name, elapsedTime.Milliseconds); orderTimes.Add(elapsedTime.Milliseconds); } catch (OperationCanceledException e) { Debug.WriteLine("A cancellation for {0} is requested.", Thread.CurrentThread.Name); } } } } double averageOrderTime = orderTimes.Count == 0 ? 0.0 : orderTimes.Average(); Console.WriteLine("{0}: ARTOC: {1} ms", Thread.CurrentThread.Name, averageOrderTime); }