0

我写了一个简单的生产者-消费者队列。处理安全句柄时不断抛出错误。

namespace ConsoleApplication1
{
public class ProducerConsumer:IDisposable
{
    private Queue<string> tasks = new Queue<string>();
    Thread work;
    readonly object obj=new object();
    EventWaitHandle wh = new AutoResetEvent(true);
    public ProducerConsumer()
    {
        work = new Thread(doWork);
        work.Start();
    }
    public void doWork()
    {
        while (true)
        {
            string task = null;
            wh.WaitOne();
            lock (obj){
                if (tasks.Count > 0)
                {
                    task = tasks.Dequeue();
                    if (task == null) return;
                    else
                        {
                            Console.WriteLine("Performing task: " + task);
                            Thread.Sleep(1000);  // simulate work...
                        }
                }
            }

        }
    }
    public void ShutDown()
    {
        tasks.Enqueue(null);
        wh.Close();
        work.Join(); 
    }
    public void Dispose()
    {
       tasks.Enqueue(null);
       wh.Close();
       work.Join(); 
    }
    public void AddTask(string str)
       {
        lock(obj){tasks.Enqueue(str);wh.Set();}
       }
}
class Program
    {
        static EventWaitHandle _waitHandle = new AutoResetEvent(false);
        static void Main(string[] args)
        {
            ProducerConsumer prod = new ProducerConsumer();
            prod.AddTask("Started");
            for (int i = 0; i < 5; i++) prod.AddTask(Convert.ToString(i));
            prod.AddTask("Done");
            prod.ShutDown();
            Console.ReadLine();
        }
    }
}

如果我将 wh.WaitOne() 更改为 else 部分,那么它开始工作

public void doWork()
    {
        while (true)
        {
            string task = null;

            lock (obj){
                if (tasks.Count > 0)
                {
                    task = tasks.Dequeue();
                    if (task == null) return;
                    else
                        {
                            Console.WriteLine("Performing task: " + task);
                            Thread.Sleep(1000);  // simulate work...
                        }
                }
                else
                    wh.WaitOne();
            }

        }
    }

有人可以解释为什么会这样吗?

4

0 回答 0