<commit_before>﻿//#define UseBlockingCollection

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
#if UseBlockingCollection
using System.Collections.Concurrent;
#endif

#if !UseBlockingCollection
using MultithreadDesignPattern.ProducerConsumer;

#endif

namespace ProducerConsumer.ConsoleApp
{
    internal class Program
    {
        private static void Main()
        {
            const int channelCapacity = 3;

            const int producerCount = 3;
            const int producerWorkload = 1500;

            const int consumerCount = 3;
            const int consumerWorkload = 3000;

#if !UseBlockingCollection
            var channel = new Channel<string>(channelCapacity);
            var producers = new List<Producer>();
            var consumers = new List<Consumer>();
#else
            // By calling other constructor overloads of BlockingCollection<T>,
            // it becomes possible to switch algorithm of the collection among
            // FIFO (ConcurrentQueue<T>), LIFO (ConcurrentStack<T>) and so on.
            var channel = new BlockingCollection<string>(channelCapacity);
            var producers = new List<ProducerBlockingCollection>();
            var consumers = new List<ConsumerBlockingCollection>();
#endif

            for (int i = 0; i < producerCount; i++)
            {
                var producer =
#if !UseBlockingCollection
                    new Producer(
#else
                    new ProducerBlockingCollection(
#endif
                        "Producer#" + i, producerWorkload, channel);
                Task.Run(() => producer.Run());
                producers.Add(producer);
            }

            for (int i = 0; i < consumerCount; i++)
            {
                var consumer =
#if !UseBlockingCollection
                    new Consumer(
#else
                    new ConsumerBlockingCollection(
#endif
                        "Consumer#" + i, consumerWorkload, channel);
                Task.Run(() => consumer.Run());
                consumers.Add(consumer);
            }

            Console.ReadLine();
            producers.ForEach(p => p.Shutdown());
            consumers.ForEach(c => c.Shutdown());
            Console.ReadLine();
#if UseBlockingCollection
            channel.Dispose();
#endif
        }
    }
}<commit_msg>Reduce the number of #if-#else-#endif directives in Program.cs for code simplicity.<commit_after>﻿//#define UseBlockingCollection

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
#if !UseBlockingCollection
using ChannelType = MultithreadDesignPattern.ProducerConsumer.Channel<string>;
using ProducerType = ProducerConsumer.ConsoleApp.Producer;
using ConsumerType = ProducerConsumer.ConsoleApp.Consumer;

#else
using ChannelType = System.Collections.Concurrent.BlockingCollection<string>;
using ProducerType = ProducerConsumer.ConsoleApp.ProducerBlockingCollection;
using ConsumerType = ProducerConsumer.ConsoleApp.ConsumerBlockingCollection;

#endif

namespace ProducerConsumer.ConsoleApp
{
    internal class Program
    {
        private static void Main()
        {
            const int channelCapacity = 3;

            const int producerCount = 3;
            const int producerWorkload = 1500;

            const int consumerCount = 3;
            const int consumerWorkload = 3000;

            // By calling other constructor overloads of BlockingCollection<T>,
            // it becomes possible to switch algorithm of the collection among
            // FIFO (ConcurrentQueue<T>), LIFO (ConcurrentStack<T>) and so on.
            var channel = new ChannelType(channelCapacity);
            var producers = new List<ProducerType>();
            var consumers = new List<ConsumerType>();

            for (int i = 0; i < producerCount; i++)
            {
                var producer = new ProducerType("Producer#" + i, producerWorkload, channel);
                Task.Run(() => producer.Run());
                producers.Add(producer);
            }

            for (int i = 0; i < consumerCount; i++)
            {
                var consumer = new ConsumerType("Consumer#" + i, consumerWorkload, channel);
                Task.Run(() => consumer.Run());
                consumers.Add(consumer);
            }

            Console.ReadLine();
            producers.ForEach(p => p.Shutdown());
            consumers.ForEach(c => c.Shutdown());
            Console.ReadLine();
#if UseBlockingCollection
            // BlockingCollection<T> implements IDisposable.
            channel.Dispose();
#endif
        }
    }
}
{'fraction_non_alphanumeric': 0.0935455734845181, 'fraction_numerical': 0.0056694286960314, 'mean_word_length': 2.1656314699792962, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3000656', 'n_tokens_mistral': 1169, 'n_tokens_neox': 1111, 'n_words': 309}