avatar

Thread Safe Queue

опубликовал в Unity3D / Программирование
Во время разработки одного из своих проектов столкнулся с тем, что С# Unity 4, не поддерживает System.Collections.Concurrent, что достаточно грустно, если у вас появится желание прикрутить простые многопоточные задачи, как например просчет чего то в бэкграунде.

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

using System;

using System.Collections.Generic;

public class ConcurrentQueue<T>{

   private readonly object syncLock = new object();

   private Queue<T> queue;


   public int Count

   {

      get

      {

        lock(syncLock)

        {

             return queue.Count;

        }

       }

    }
    public ConcurrentQueue()

    {

        this.queue = new Queue<T>();

    }


    public void Enqueue(T item)

    {

       lock(syncLock)

       { 

          queue.Enqueue(item);

       }

     }

     public T Dequeue()

     {

        lock(syncLock)

        {

           return queue.Dequeue();

        }

      }

      public void Clear()

      {

         lock(syncLock)

         {

            queue.Clear();

         }

      }


}


Gits Link
+2
1
1545
  • 9 комментариев

    avatar
    А, собственно, зачем? Можно же проще :)
    avatar
    Продемонстрируете?
    avatar
    Зависит исключительно от ситуации же?
    Вообще, как мне кажется, проще было бы унаследоваться от Queue или просто лочить его перед обращением, если таких мест не много. Я не фанат создания тонн классов.
    avatar
    Я вот например не уверен что в Queue эти методы виртуальные.
    Я не фанат повторяющегося кода, проще завести класс, чем копипастить, на то это и ООП.
    avatar
    И самое главное наследование от Queue делает его уже не ThreadSafe, т.к. публичные методы Queue не ThreadSafe, а следовательно у тебя будет куча методов которые нельзя дергать, и часть которые можно, а это уже каша и требует документации.
    avatar
    А как же, например, Synchronized?
    avatar
    Ну например потому, что Synchronized гарантирует только для низкоуровневых операций, так что что либо более менее крупное все равно надо оборачивать в еще один слой lock, опять же копипаста, а так это можно убрать в класс.
    avatar
    Вас понял, вопрос снят :)
    avatar
    В-нулевых, наследоваться от очереди вредно. Никто не гарантирует потокобезопасность.

    Во-первых, необязательно в данном классе создавать объект для лока, если можно для этого использовать сам queue.
    Во-вторых, поскольку текущий рендер (я про unity 4 говорю) работает в одном потоке, очередь без возврата в главный тред не особо применима в unity.
    Ну и зачем огородить самописный огород, когда есть Loom и lock-free очереди?
    Чтобы оставить комментарий необходимо .