C# 线程安全队列<;t>;在C中#

C# 线程安全队列<;t>;在C中#,c#,.net,multithreading,queue,C#,.net,Multithreading,Queue,我需要创建一个通用队列,该队列可以由多个生产者排队,也可以由多个消费者取消排队 我希望系统至少尝试两次,以防在系统更改期间尝试操作,因此如果进程线程失败,现在标记的qBit将再次排队,然后在再次处理时,执行该操作的线程将知道另一个线程已经尝试过此操作一次,如果失败,将此特定事件发送到补救队列以进行外部干预 所以。。。。对于实际问题,我意识到队列的状态可能会在contains()和队列操作之间发生变化,就像套接字检查只是错误控制的一种形式,而不是替换。我没有这样做,因为当两个相同id(由GUID标

我需要创建一个通用队列,该队列可以由多个生产者排队,也可以由多个消费者取消排队

我希望系统至少尝试两次,以防在系统更改期间尝试操作,因此如果进程线程失败,现在标记的qBit将再次排队,然后在再次处理时,执行该操作的线程将知道另一个线程已经尝试过此操作一次,如果失败,将此特定事件发送到补救队列以进行外部干预

所以。。。。对于实际问题,我意识到队列的状态可能会在contains()和队列操作之间发生变化,就像套接字检查只是错误控制的一种形式,而不是替换。我没有这样做,因为当两个相同id(由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;
        }
    }
}
公共类tsQueue
{
对象同步锁=新对象();
专用队列Q=新队列();
列表内容=新列表();
公共qBit出列()
{
锁定(同步锁定)
{
qBit pop=Q.Dequeue();
内容。删除(弹出项);
返回流行音乐;
}
}
公共无效排队(qBit推送)
{
锁定(同步锁定)
{
contents.Add(推送项);
排队(推);
}
}
公共布尔包含(t检查){
锁定(同步锁定)
{
返回内容。包含(检查);
}
}
公共类qBit
{
公共布尔标志{get;set;}
私人信托基金项目;
公共t项{get{return\u item;}}
公共qBit(t项)
{
本项目=项目;
}
}
}

ConcurrentQueue是一个线程安全的实现,它完全满足您的需要。它也肯定会更快,你自己的代码。使用此选项可以查看ConcurrentQueue实现的源代码。

您是否查看了
ConcurrentQueue
?我认为这是线程安全的@phoog我想用这两种方法对解决方案进行基准测试。根据我的经验,有时手动锁定非线程安全的对象实际上比使用线程安全的对象(即使用队列与ConcurrentQueue)要快。但是,我认为在使用这两个选项之间的选择必须是特定于应用的。@ pHyFurDead如果性能是个问题,那么,我们应该做一个基准测试,并考虑哪种解决方案更快。库解决方案通常比手工轧制的解决方案慢;库需要逻辑来处理可能与所讨论的用例无关的条件。但库代码也可能比手工编写的代码得到更好的测试,更不用说经过更彻底的思考了。因此,更好的性能带来的好处(如果基准测试确实显示出更好的性能)应该与测试和调试的成本进行权衡,以确保正确性。为什么要使用驼峰式的方法?驼峰式的方法是习惯的力量,我一直在语言中来回跳跃,除了我之外,没有人能看到它的内部,所以我倾向于坚持我的眼睛习惯于阅读的东西。其他的回答也与答案及其相关性有关。我查看了ConcurrentQueue,发现了一些关于它的问题,这里提到的问题让我不那么确定,所以我尝试了一种可能更长的方法,但更容易窥探。我不认为性能会是一个问题,它不是非常高的性能,只是必须是毫无疑问的可靠。