Всем привет. Сегодня поговорим про потокобезопасные очереди (ConcurrentQueue). Потокобезопасные очереди - очереди, которые можно использовать в потоках и не переживать про то, что один объект из очереди может попасть в один и тот же поток. Рассмотрим создание объекта, здесь нет ничего не обычного по сравнению с обычной Queue, кроме того, что в параллельной очереди нельзя задать ее емкость (Capacity) в круглых скобках. Назовем объект как 'lines': ConcurrentQueue<string> lines= new ConcurrentQueue<string>(); Код ConcurrentQueue<string> lines= new ConcurrentQueue<string>(); Конечно, внутри <> можно указать желаемый (например, int) тип данных (рекомендую указывать тип всегда) Также можно скопировать какой-нибудь лист или массив в эту очередь. Для этого в классе создадим объект без инициализации: ConcurrentQueue<string> lines; Код ConcurrentQueue<string> lines; Затем в каком-нибудь методе, например startBtn_Click public void startBtn_Click(object sender, EventArgs e) { // тут куча кода, которая не интересна lines = new ConcurrentQueue<string>(myList); // myList - ваш лист, откуда нужно скопировать данные из листа в очередь } Код public void startBtn_Click(object sender, EventArgs e) { // тут куча кода, которая не интересна lines = new ConcurrentQueue<string>(myList); // myList - ваш лист, откуда нужно скопировать данные из листа в очередь } Ни в коем случае не пишите никогда что-то типо такого для копирования данных из одного объекта в другой: ConcurrentQueue<string> lines = new ConcurrentQueue<string>(); ConcurrentQueue<string> newLines = new ConcurrentQueue<string>(); lines.Enqueue("test"); lines.Enqueue("for"); lines.Enqueue("lolzteam.org"); newLines = lines; Код ConcurrentQueue<string> lines = new ConcurrentQueue<string>(); ConcurrentQueue<string> newLines = new ConcurrentQueue<string>(); lines.Enqueue("test"); lines.Enqueue("for"); lines.Enqueue("lolzteam.org"); newLines = lines; Так вы не скопируете данные из lines в newLines, а просто сделаете очередь newLines ссылкой на lines. Правильно так: newLines = new ConcurrentQueue<string>(lines); Код newLines = new ConcurrentQueue<string>(lines); Теперь рассмотрим выбор и добавление объектов в очередь. Как я писал уже ранее, такой тип очереди - потокобезопасен, поэтому не нужно использовать lock для добавления/выборки данных в очереди/из очереди. Для добавления данных в очередь используется тот же метод, что и в обычной очереди: Enqueue newLines.Enqueue("lolzteam.org guide"); Код newLines.Enqueue("lolzteam.org guide"); Так писать нельзя: lock (lockThis) { newLines.Enqueue("lolzteam.org guide"); } Код lock (lockThis) { newLines.Enqueue("lolzteam.org guide"); } Метод выбора и удаления из очереди данных немного другой, но он очень прост. Для этого в вашей функции, которая используется как поток, создайте в самом начале переменную string item. string item; lines.TryDequeue(out item); Код string item; lines.TryDequeue(out item); Ещё лучше проверять очередь на наличие элементов, для этого используйте bool метод isEmpty, а потом проверять string item на наличие в ней символов: string item; if (!lines.IsEmpty) { lines.TryDequeue(out item); } if (string.IsNullOrEmpty(item) { // выходим из цикла или завершаем поток } Код string item; if (!lines.IsEmpty) { lines.TryDequeue(out item); } if (string.IsNullOrEmpty(item) { // выходим из цикла или завершаем поток } Модификатор параметра out указывать обязательно! На сегодня всё! Если у вас остались вопросы, спрашивайте.
бамп Queue mySafeQueue = Queue.Synchronized(myNotSafeQueue); Код Queue mySafeQueue = Queue.Synchronized(myNotSafeQueue);