themhz
themhz

Reputation: 8424

Lock a single access variable for parallel threads in C#

Hello i have this code

var queue = new BlockingCollection<int>();
            queue.Add(0);            
            var producers = Enumerable.Range(1, 3)
                .Select(_ => Task.Factory.StartNew(()=>
                    {

                    Enumerable.Range(1, queue.Count)
                            .ToList().ForEach(i =>
                                {

                                    lock (queue)
                                        {
                                            if (!queue.Contains(i))
                                            {
                                                Console.WriteLine("Thread" + Task.CurrentId.ToString());
                                                queue.Add(i);
                                            }
                                        }
                                    Thread.Sleep(100);

                                });

                    }))
                 .ToArray();

            Task.WaitAll(producers);
            queue.CompleteAdding();

                foreach (var item in queue.GetConsumingEnumerable())
                {                    
                        Console.WriteLine(item.ToString());               
                }   

But i need each time that a single thread ads something to the queue.Add(i) the Enumerable.Range(1, queue.Count) to be inceased so that the code executes until there are no more items to be added to the queue. I hope you understand the question. In other words i need this action to run infinitely untill i tell it to stop. Any suggestions?

Upvotes: 0

Views: 1440

Answers (2)

George Mamaladze
George Mamaladze

Reputation: 7931

I see, what you need is a BlockingCollection which came with .NET 4.0. It allows to implement the Producer-Consumer pattern.

Multiple threads or tasks can add items to the collection concurrently. Multiple consumers can remove items concurrently, and if the collection becomes empty, the consuming threads will block and wait until a producer adds an item. Over and over again ...

... until a special method will be called by producer to identify the end, saying consumer "Hey, stop waiting there - nothing will come anymore!".

I am not posting code samples, because there are some under given link. You can find much more if you just google for Producer-Consumer pattern and/or BlockingCollection.

Upvotes: 1

Imperatorn
Imperatorn

Reputation: 272

I´m sorry to say, but I can´t understand your motives for writing something like that without further explaination :(

Is the following code useful to you in any way? Because I don´t think it is :P

        int n = 2;

        Task[] producers = Enumerable.Range(1, 3).Select(_ => 
            Task.Factory.StartNew(() =>
                {
                    while (queue.Count < n)
                    {
                        lock (queue)
                        {
                            if (!queue.Contains(n))
                            {
                                Console.WriteLine("Thread" + Task. CurrentId);
                                queue.Add(n);

                                Interlocked.Increment(ref n);
                            }
                        }

                        Thread.Sleep(100);
                    }
                }))
            .ToArray();

I mean, it will just go on and on. It´s like a reeeeeeaaallllyyy strange way of just adding numbers to a List

Please explain you objective and we might be able to help you.

Upvotes: 1

Related Questions