等待句柄出错

时间:2014-09-04 13:52:36

标签: c# autoresetevent

我编写了一个简单的Producer-Consumer队列。它不断抛出安全手柄处理的错误。

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();
            }

        }
    }

有人可以说明为什么会这样吗?

0 个答案:

没有答案