//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
using System;
using System.Threading;

namespace ProfilingSamples
{
	public class LogicalThreadMain 
	{
		private ManualResetEvent [] asyncEvents;
		const int threadCount = 100;
		public LogicalThreadMain()
		{
			asyncEvents = new ManualResetEvent[threadCount];
			for(int i = 0;i < threadCount;i++)
			{
				asyncEvents[i] = new ManualResetEvent(false);
			}
		}
		void WorkerThread(Object number) 
		{
			int id = (int)number;
			// Uśpienie na 1 sekundę w celu symulacji rzeczywistej pracy
			Thread.Sleep(1000);
			// Zasygnalizowanie końca operacji asynchronicznej.
			TimeSpan ts = new TimeSpan(Environment.TickCount);
			Console.WriteLine("{0} {1}", id, ts);
			asyncEvents[id].Set();
		}
		void TestThread()
		{
			try
			{
				while(true)
				{ 
					Console.WriteLine("Początek ----------------");
					for(int i = 0;i < threadCount;i++)
					{
						ThreadPool.QueueUserWorkItem(new WaitCallback(WorkerThread), i);
					}
					Console.WriteLine("Koniec ----------------");
					for(int i = 0;i < threadCount;i++)
					{
						asyncEvents[i].WaitOne();
						asyncEvents[i].Reset();
					}
				}
			}
			catch(Exception e)
			{
				Console.WriteLine("TestThread przerywa pracę: {0}", e.Message);
			}
		}
		static void Main(string [] args)
		{
			LogicalThreadMain m = new LogicalThreadMain();
			Thread testThread = new Thread(new ThreadStart(m.TestThread));
			testThread.Start();
			string input = Console.ReadLine();
			testThread.Abort();
			testThread.Join();
		}
	}
}