Блокировка одной переменной доступа для параллельных потоков в C # - PullRequest
0 голосов
/ 28 января 2012

Здравствуйте, у меня есть этот код

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());               
                }   

Но мне нужно каждый раз, когда один поток объявляет что-то в очередь. Добавлять (i) Enumerable.Range (1, queue.Count), который нужно увеличитьтак что код выполняется до тех пор, пока не останется больше элементов, добавляемых в очередь.Я надеюсь, вы понимаете вопрос.Другими словами, мне нужно, чтобы это действие выполнялось бесконечно, пока я не скажу, чтобы оно прекратилось.Есть предложения?

Ответы [ 2 ]

1 голос
/ 29 января 2012

Понятно, что вам нужен BlockingCollection, поставляемый с .NET 4.0. Это позволяет реализовать шаблон Производитель-Потребитель.

Несколько потоков или задач могут добавлять элементы в коллекцию одновременно. Несколько потребителей могут удалять элементы одновременно, и если коллекция становится пустой, потоки-потребители будут блокировать и ждать, пока производитель не добавит элемент. Снова и снова ...

... до тех пор, пока производитель не вызовет специальный метод для определения конца, сказав потребителю: «Эй, хватит ждать - ничего больше не придет!».

Я не публикую примеры кода, потому что есть некоторые по данной ссылке. Вы можете найти гораздо больше, если вы просто Google для Шаблон производитель-потребитель и / или BlockingCollection.

1 голос
/ 29 января 2012

Прошу прощения, но я не могу понять ваши мотивы написания чего-либо подобного без дальнейших объяснений: (* ​​1001 *

Вам полезен следующий код? Потому что я недумаю, что это: 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();

Я имею в виду, это будет продолжаться и продолжаться. Это как странный способ просто добавить цифры в список

Пожалуйста, объясните вашу цельи мы сможем вам помочь.

...