Блокировка одной переменной доступа для параллельных потоков в C#
Привет у меня есть этот код
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 ответа
Извините, но я не могу понять ваши мотивы для написания чего-либо подобного без дальнейших объяснений:(
Вам полезен следующий код? Потому что я не думаю, что это так: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();
Я имею в виду, это будет продолжаться и продолжаться. Это как странный способ просто добавить цифры в список.
Пожалуйста, объясните вашу цель, и мы сможем вам помочь.
Я вижу, что вам нужно это BlockingCollection
который пришел с.NET 4.0. Это позволяет реализовать шаблон "производитель-потребитель".
Несколько потоков или задач могут добавлять элементы в коллекцию одновременно. Несколько потребителей могут удалять элементы одновременно, и если коллекция становится пустой, потоки-потребители будут блокировать и ждать, пока производитель не добавит элемент. Снова и снова...
... до тех пор, пока производитель не вызовет специальный метод для определения конца, сказав потребителю: "Эй, хватит ждать - ничего больше не придет!"
Я не публикую примеры кода, потому что есть некоторые по данной ссылке. Вы можете найти гораздо больше, если просто гуглите по шаблону Producer-Consumer и / или BlockingCollection
,