/// <summary> /// /// Subscribes a producer to let him load data into /// the consumer. /// /// </summary> /// <param name="dataProducer"></param> public void Subscribe(DataProducer dataProducer) { lock (subscribedProducers) { subscribedProducers.Add(dataProducer); } }
/// <summary> /// /// Signals the end of data of a specific data producer. /// /// If there are no data producers active yet, then we /// can signal to the buffer that the data loading process /// is finished- /// /// </summary> public void SetEndOfData(DataProducer dataProducer) { lock (subscribedProducers) { subscribedProducers.Remove(dataProducer); if (subscribedProducers.Count == 0) { Buffer.SetEndOfData(); } } }
/// <summary> /// /// Creates the array of producers threads /// /// Each producer will provide rows to a consumer. The consumer is /// computer using the modulo operator (%) in order to get a /// round robin policy between consumers. /// /// Please note that if numberOfProducers % numberOfConsumers is not /// zero (that is one is not a multiple of the other) then the load /// of rows will be unbalanced and the final result will be more /// difficult to understand, since some consumer threads will have /// processed more rows. /// /// </summary> private static void CreateProducers() { for (int i = 0; i < numberOfProducers; i++) { int consumerIndex = i % numberOfConsumers; DataConsumer consumer = dataConsumers[consumerIndex]; DataProducer producer = new DataProducer(); // // Please note that we need to subscribe before to start // all the threads, since a single thread might not be able // to subscribe before all the others have ended sending rows // and this would cause the consumer to stop receiving rows. // consumer.Subscribe(producer); Thread newThread = new Thread(delegate() { producer.Produce(consumer, numberOfRows / numberOfProducers); consumer.SetEndOfData(producer); }); producerThreads.Add(newThread); } }