C#线程和队列

neo*_*r99 11 c# multithreading

这不是关于我能够或应该以最佳方式利用队列的不同方法,而是我所看到的对我来说毫无意义的事情.

void Runner() {
    // member variable
    queue = Queue.Synchronized(new Queue());
    while (true) {
        if (0 < queue.Count) {
            queue.Dequeue();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是在一个线程中运行的:

var t = new Thread(Runner);
t.IsBackground = true;
t.Start();
Run Code Online (Sandbox Code Playgroud)

其他事件是"排队"其他地方.我所见到的是在一段时间内,Dequeue实际上会抛出InvalidOperationException,队列为空.这应该是不可能看到计数如何保证那里有东西,我很肯定没有别的东西是"出列".

问题:

  1. Enqueue是否有可能在项目完全进入队列之前实际增加计数(无论这意味着什么......)?
  2. 线程是否有可能在Dequeue语句中以某种方式重新启动(到期,重置...),但是在它已经删除了一个项目之后立即?

编辑(澄清):

这些代码片段是实现后台帮助程序线程的Wrapper类的一部分.此处的Dequeue是唯一的Dequeue,并且所有Enqueue/Dequeue都在Synchronized成员变量(队列)上.

Eri*_*bal 11

使用Reflector,您可以看到不,在添加项目之前,计数不会增加.

正如本指出的那样,看起来你确实有多个人叫出列.

你说你是积极的,没有别的东西叫出列.是因为你只有一个线程调用dequeue?是否在任何其他地方都被叫出去?

编辑:

我写了一些示例代码,但无法重现问题.它只是保持运行和运行,没有任何例外.

在你出错之前它运行了多长时间?也许你可以分享更多的代码.

class Program
{
    static Queue q = Queue.Synchronized(new Queue());
    static bool running = true;

    static void Main()
    {
        Thread producer1 = new Thread(() =>
            {
                while (running)
                {
                    q.Enqueue(Guid.NewGuid());
                    Thread.Sleep(100);
                }
            });

        Thread producer2 = new Thread(() =>
        {
            while (running)
            {
                q.Enqueue(Guid.NewGuid());
                Thread.Sleep(25);
            }
        });

        Thread consumer = new Thread(() =>
            {
                while (running)
                {
                    if (q.Count > 0)
                    {
                        Guid g = (Guid)q.Dequeue();
                        Console.Write(g.ToString() + " ");
                    }
                    else
                    {
                        Console.Write(" . ");
                    }
                    Thread.Sleep(1);
                }
            });
        consumer.IsBackground = true;

        consumer.Start();
        producer1.Start();
        producer2.Start();

        Console.ReadLine();

        running = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在这一点上,我所能建议的是:(1)你进入了If部分,(2)太阳耀斑将你的位翻转为零,(3)你的队列引发了异常.它真的应该抛出一个SolarFlareException,但无论如何.Potatoto,Potahto. (8认同)