private ConcurrentLinkedList <BOX <int> > AddCheckEntries(bool bTail = true, int countEntries = 10) { var LL = new ConcurrentLinkedList <BOX <int> >(); var n = new List <int>(Enumerable.Range(0, countEntries)); foreach (var i in n) { if (bTail) { LL.AddTail(new BOX <int>(i)); } else { LL.AddHead(new BOX <int>(i)); } } var nFound = 0; var node = LL.Head; do { Assert.AreNotEqual(node.Value, null); Assert.AreEqual(true, n.Contains(node.Value.VALUE)); nFound++; }while ((node = node.Next) != null); Trace.WriteLine(string.Format("Total Entries {0}", LL.Count), "info"); Assert.AreEqual(nFound, n.Count); return(LL); }
public void AddAtTailCheckCount() { var LL = new ConcurrentLinkedList <BOX <int> >(); var n = Enumerable.Range(0, 100); foreach (var i in n) { LL.AddTail(new BOX <int>(i)); } Trace.WriteLine(string.Format("Total Entries{0}", LL.Count), "info"); Assert.AreEqual(LL.Count, n.Count()); }
private ConcurrentLinkedList <BOX <long> > CreateProducersConsumers(int countEntries, int TailProducers, int TailConsumers, int HeadProducers, int HeadConsumers, int MaxProducerRandomDelay, int MaxConsumersRandomDelay, int InitialConsumerDelay = 10) { var currentEntry = 0; var totalProduced = 0; var totalConsumed = 0; var LL = new ConcurrentLinkedList <BOX <long> >(); var rnd = new Random(); List <Task <int> > consumerTasks = new List <Task <int> >(); List <Task <int> > producerTasks = new List <Task <int> >(); Func <bool, string, Task <int> > producer = async(bIsTail, producerId) => { var produced = 0; Trace.WriteLine(string.Format("Producer {0} is {1}", producerId, bIsTail ? "Tail" : "Head")); while (Interlocked.Increment(ref currentEntry) <= countEntries) { produced++; var newVal = DateTime.UtcNow.Ticks; Trace.WriteLine(string.Format("Producer {0} + {1}", producerId, newVal)); if (bIsTail) { LL.AddTail(new BOX <long>(newVal)); } else { LL.AddHead(new BOX <long>(newVal)); } await Task.Delay(rnd.Next(0, MaxProducerRandomDelay)); } return(produced); }; Func <bool, string, Task <int> > consumer = async(bIsTail, consumerId) => { // all consumer wait a bit this almost elminate the need for that CX below await Task.Delay(InitialConsumerDelay); // Trace.WriteLine(string.Format("Consumer {0} is {1}", consumerId, bIsTail ? "Tail" : "Head")); var consumed = 0; BOX <long> node; while ((bIsTail && null != (node = LL.RemoveTail())) || (!bIsTail && null != (node = LL.RemoveHead()))) { Assert.AreNotEqual(null, node.VALUE); Trace.WriteLine(string.Format("Consumer {0} - {1}", consumerId, node.VALUE)); consumed++; await Task.Delay(rnd.Next(0, MaxConsumersRandomDelay)); } Trace.WriteLine(string.Format("Consumer {0} is {1} -- Exited", consumerId, bIsTail ? "Tail" : "Head")); return(consumed); }; // give a head start for consumers. for (int p = 1; p <= TailProducers + HeadProducers; p++) { //avoid hoisted variables. var isTail = (TailProducers > 0 && p <= TailProducers); var producerName = string.Concat("P", p); producerTasks.Add(Task.Run( async() => await producer(isTail, producerName)) ); } for (int c = 1; c <= TailConsumers + HeadConsumers; c++) { var isTail = (TailConsumers > 0 && c <= TailConsumers); var consumerName = string.Concat("C", c); consumerTasks.Add(Task.Run( async() => await consumer(isTail, consumerName)) ); } Task.WhenAll(producerTasks).Wait(); Task.WhenAll(consumerTasks).Wait(); // if after all said and done we still have items consume them. if (LL.Count > 0) { Trace.WriteLine("Consumers exited before producers completed work, creating a CX", "warnings"); totalConsumed += Task <int> .Run(async() => await consumer(true, "CX")).Result; } // calculate all produced and consumed foreach (var p in producerTasks) { totalProduced += p.Result; } foreach (var c in consumerTasks) { totalConsumed += c.Result; } // are we clean? Trace.WriteLine(string.Format("completed produced:{0} consumed:{1}", totalProduced, totalConsumed), "info"); Assert.AreEqual(totalProduced, totalConsumed); return(LL); }