Мне нужно создать общую очередь, которая может быть поставлена в очередь моими несколькими производителями и отключена несколькими потребителями.Thread safe Queue <t> in C#
Я хочу, чтобы система, по крайней мере, дважды пыталась выполнить попытку операции во время изменений в системе, поэтому, если поток процессов не работает, теперь помеченный qBit снова ставится в очередь, а затем при повторной обработке поток, выполняющий эту операцию будет знать, что другой поток уже пробовал эту операцию один раз, и если он терпит неудачу, отправьте этот конкретный запрос в очередь исправления для внешнего вмешательства.
Итак, в настоящий вопрос, я понимаю, что состояние очереди может меняться между contains() и операцией очереди, например, проверка сокетов - это просто форма контроля ошибок, а не замена. Я сделал это так, потому что два потока производителей могут в противном случае подбрасывать ошибку, когда два из одного и того же идентификатора (идентифицированные GUID) пытаются и очереди, что в противном случае было бы другими объектными экземплярами qBit.
Вопрос в том, является ли это разумной реализацией? Я не вижу, чтобы он зашел в тупик, потому что все методы вернутся независимо от результата обработки qBit, и это позволяет мне несколько предотвратить некоторые из них.
Мысли и/или второй комплект глаз, пожалуйста?
public class tsQueue<t>
{
object syncLock = new object();
private Queue<qBit<t>> Q = new Queue<qBit<t>>();
List<t> contents = new List<t>();
public qBit<t> deQueue()
{
lock (syncLock)
{
qBit<t> pop = Q.Dequeue();
contents.Remove(pop.item);
return pop;
}
}
public void enQueue(qBit<t> push)
{
lock (syncLock)
{
contents.Add(push.item);
Q.Enqueue(push);
}
}
public bool contains(t check) {
lock (syncLock)
{
return contents.Contains(check);
}
}
public class qBit<t>
{
public bool flag { get; set; }
private t _item;
public t item { get { return _item; } }
public qBit(t item)
{
this._item = item;
}
}
}
Вы смотрели 'ConcurrentQueue'? –
phoog
Это выглядит безопасным для меня потоком. @phoog Я хотел бы сравнить решение с обоими. В моем опыте иногда вручную блокировка объекта, не связанного с потоками, на самом деле быстрее, чем использование объекта, который является потокобезопасным (например, с использованием очереди с ConcurrentQueue). Но, я думаю, выбор между этими двумя должен быть специфичным для приложения. – phishfordead
@phishfordead, если производительность является проблемой, да, нужно проверить и рассмотреть, какое решение выполняется быстрее. Библиотечные решения часто медленнее, чем ручные решения; библиотека нуждается в логике для решения условий, которые могут быть неактуальны для рассматриваемого случая использования. Но библиотечный код также, скорее всего, будет лучше проверен, чем ручной код, не говоря уже о более тщательном анализе. Таким образом, преимущества лучшей производительности (если действительно бенчмаркинг показывает лучшую производительность) следует сопоставить с затратами на тестирование и отладку для обеспечения правильности. – phoog