вопрос по AutoResetEvent
От: Аноним  
Дата: 19.09.09 20:23
Оценка:
Доброго времени суток!

не понятен вывод следующего кода (слегка измененный пример Producer/Consumer из здесь
Автор(ы): Joseph Albahari
Дата: 24.03.2007
Подробно рассматривается работа с потоками — запуск, завершение, прерывание, блокировки, синхронизация, контексты синхронизации, особенности взаимодействия с апартаментами, а также потоковые возможности .NET — потоковые таймеры, пулы потоков, BackgroundWorker, асинхронные методы и делегаты.
В статье использован материал из книги Joseph Albahari, Ben Albahari "C# 3.0 in a Nutshell" — http://www.oreilly.com/catalog/9780596527570/
)


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ProducerConsumerQueue q = new ProducerConsumerQueue();
            Thread.Sleep(1000);    
            q.EnqueueTask("Hello");
            for (int i = 0; i < 5; i++) q.EnqueueTask("Say " + i);
            Thread.Sleep(100); 
            q.EnqueueTask("Goodbye!");

            Thread.Sleep(5000);
            q.EnqueueTask("Goodbye_II!");

            q.Dispose();
            Console.ReadLine();
        }
    }

    class ProducerConsumerQueue : IDisposable
    {
        
        EventWaitHandle wh = new AutoResetEvent(false);
        Thread worker;
        object locker = new object();
        Queue<string> tasks = new Queue<string>();

        public ProducerConsumerQueue()
        {
            worker = new Thread(Work);
            worker.Start();
        }

        public void EnqueueTask(string task)
        {
            lock (locker) tasks.Enqueue(task);
            wh.Set();
        }

        public void Dispose()
        {
            EnqueueTask(null);     // Signal the consumer to exit.
            worker.Join();          // Wait for the consumer's thread to finish.
            wh.Close();             // Release any OS resources.
        }

        void Work()
        {
            while (true)
            {
                string task = null;
                lock (locker)
                    if (tasks.Count > 0)
                    {
                        task = tasks.Dequeue();
                        if (task == null) 
                            return;
                    }

                if (task != null)
                {
                    Console.WriteLine("Performing task: " + task);
                    Thread.Sleep(500);  // simulate work...
                }
                else
                {
                    Console.WriteLine("Waiting.." );
                    wh.WaitOne();         // No more tasks - wait for a signal
                }
            }
        }
    }
}


вывод

Waiting..
Performing task: Hello
Performing task: Say 0
Performing task: Say 1
Performing task: Say 2
Performing task: Say 3
Performing task: Say 4
Performing task: Goodbye!
Waiting..
Waiting..
Performing task: Goodbye_II!

вопрос: почему Waiting.. два раза?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.