使用事件AutoResetEvent/ManualResetEvent

假如一个线程处理任务,保持了一个任务队列;其它几个线程向该任务队列中添加任务。
我们要保证这个任务队列不能过大,比如每一个时刻,只能有3个任务在队列中,使用事件

(AutoResetEvent/ManualResetEvent)机制如下:

 

namespace ManualResetEventTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Process processObj = new Process();
            ThreadStart newProcessStart = new ThreadStart(processObj.ProcessTask);
            Thread newThread = new Thread(newProcessStart);
            newThread.Start();


            //任务产生线程1
            Monitor monitorObj = new Monitor();
            monitorObj.processObj = processObj;
            ThreadStart newMonitorStart = new ThreadStart(monitorObj.GenerateTask);
            Thread newMonitorThread = new Thread(newMonitorStart);
            newMonitorThread.Start();

            //任务产生线程1
            Monitor monitorObj2 = new Monitor();
            monitorObj2.processObj = processObj;
            ThreadStart newMonitorStart2 = new ThreadStart(monitorObj2.GenerateTask);
            Thread newMonitorThread2 = new Thread(newMonitorStart2);
            newMonitorThread2.Start();

            Console.ReadLine();
        }
    }

    class Task
    {
        private static int refCount = 0;
        private int taskID = 0;

        public int TaskID
        {
            get { return taskID; }
        }
        public int RefCount
        {
            get { return refCount; }
        }

        public Task()
        {
            refCount++;
            taskID = RefCount;
        }
    }

    class Process
    {
        private Queue<Task> taskList = new Queue<Task>();
        private Random random = new Random();
        private object obj = new object();

        //用于保证任务队列taskList中,始终只有少量任务等待被处理
        public ManualResetEvent manualEvent = new ManualResetEvent(true);//初始状态,设置manualEvent被设置为Set

        public void ProcessTask()
        {
            while(true)
            {
                if (taskList.Count > 0)
                {
                    Console.WriteLine("current task count:{0}", taskList.Count);
                    Task task = taskList.Dequeue();
                    ProcessTask(task);
                    if (taskList.Count < 3)
                    {
                        manualEvent.Set(); //任务数量少于3,正在WaitOne的线程可以执行了
                    }
                    else
                    {
                        manualEvent.Reset();//任务数量太多了,所有线程都得WaitOne
                    }
                }
                else
                {
                    Thread.Sleep(2*1000);
                }
            }
        }

        private void ProcessTask(Task task)
        {
            Console.WriteLine("process task ID:{0}",task.TaskID);
            Thread.Sleep(random.Next(10) * 1000);//每个任务处理时间,是个0~10之间的随机数
        }

        public void AddTask(Task task)
        {
            lock (obj)
            {
                taskList.Enqueue(task);
                if (taskList.Count < 3)
                {
                    manualEvent.Set(); //任务数量少于3,正在WaitOne的线程可以执行了
                }
                else
                {
                    manualEvent.Reset();//任务数量太多了,所有线程都得WaitOne
                }
            }
        }
    }

    class Monitor
    {
        public Process processObj = null;
        private Random random = new Random();
        private object obj = new object();

        public void GenerateTask()
        {
            while (true)
            {
                lock (obj)
                {


                    processObj.manualEvent.WaitOne(); //直到manualEvent被Set,才能继续执行
                    Task task = new Task();
                    processObj.AddTask(task);
                    Thread.Sleep(random.Next(3) * 1000);//产生一个任务后,需要不超过3秒钟
                }

            }
        }
    }
}

posted @ 2011-03-22 18:16  pjh123  阅读(282)  评论(0编辑  收藏  举报