Загрузка...

Thread-safe queues. Ideal solution for brutus

Thread in C# created by RaysMorgan Jan 8, 2017. 1211 views

  1. RaysMorgan
    RaysMorgan Topic starter Jan 8, 2017 Че скажете 54,006 Mar 7, 2013
    Всем привет. Сегодня поговорим про потокобезопасные очереди (ConcurrentQueue).
    Потокобезопасные очереди - очереди, которые можно использовать в потоках и не переживать про то, что один объект из очереди может попасть в один и тот же поток.

    Рассмотрим создание объекта, здесь нет ничего не обычного по сравнению с обычной Queue, кроме того, что в параллельной очереди нельзя задать ее емкость (Capacity) в круглых скобках.
    Назовем объект как 'lines':

    Code

    ConcurrentQueue<string> lines= new ConcurrentQueue<string>();

    Конечно, внутри <> можно указать желаемый (например, int) тип данных (рекомендую указывать тип всегда)

    Также можно скопировать какой-нибудь лист или массив в эту очередь.
    Для этого в классе создадим объект без инициализации:
    Code
    ConcurrentQueue<string> lines;

    Затем в каком-нибудь методе, например startBtn_Click
    Code

    public void startBtn_Click(object sender, EventArgs e)
    {
    // тут куча кода, которая не интересна
    lines = new ConcurrentQueue<string>(myList);
    // myList - ваш лист, откуда нужно скопировать данные из листа в очередь
    }

    Ни в коем случае не пишите никогда что-то типо такого для копирования данных из одного объекта в другой:

    Code

    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.

    Правильно так:
    Code

    newLines = new ConcurrentQueue<string>(lines);


    Теперь рассмотрим выбор и добавление объектов в очередь. Как я писал уже ранее, такой тип очереди - потокобезопасен, поэтому не нужно использовать lock для добавления/выборки данных в очереди/из очереди.

    Для добавления данных в очередь используется тот же метод, что и в обычной очереди: Enqueue

    Code

    newLines.Enqueue("lolzteam.org guide");

    Так писать нельзя:
    Code

    lock (lockThis) {
    newLines.Enqueue("lolzteam.org guide");
    }


    Метод выбора и удаления из очереди данных немного другой, но он очень прост.
    Для этого в вашей функции, которая используется как поток, создайте в самом начале переменную string item.

    Code

    string item;
    lines.TryDequeue(out item);

    Ещё лучше проверять очередь на наличие элементов, для этого используйте bool метод isEmpty, а потом проверять string item на наличие в ней символов:
    Code

    string item;
    if (!lines.IsEmpty) {
    lines.TryDequeue(out item);
    }
    if (string.IsNullOrEmpty(item) {
    // выходим из цикла или завершаем поток
    }

    Модификатор параметра out указывать обязательно! На сегодня всё! Если у вас остались вопросы, спрашивайте.
     
  2. iPro_inactive
    iPro_inactive Jan 31, 2017 Banned 30 Jun 15, 2016
    бамп
    Code
    Queue mySafeQueue = Queue.Synchronized(myNotSafeQueue);
     
Loading...
Top