namespace Gyak2
{
    internal class Program
    {

        private static ManualResetEvent canStart = new(false); //Opcionális, de így a threadek egyszerre indulnak el.

        private static AutoResetEvent valueGot = new(false);//Azért kell, hogy a fő thread tudja, hogy megjött az adat.
        static void Main(string[] args)
        {
            Thread t1 = new Thread(GenerateFunction);
            t1.Name = "Generator"; //Név beállítása?? Lehet, hogy nem kéri a feladat.
            Thread t2 = new Thread(Monitor);
            t2.Name = "Monitor";

            t1.IsBackground = true; //Háttérbe fut, nem blokkolja a programot a futása, ha a fő thread befejeződik, akkor ez is leáll.
            t2.IsBackground = true;

            t1.Start();
            t2.Start();

            canStart.Set(); //Közös indítás.

            for(var i = 0; i < 8; i++)
            {
                valueGot.WaitOne(); //Vár amíg nem jön ú adat.
                lock (sync)
                { //Kell a lock, hogy a jó értéket írja ki, ne egy köztes állapotot.
                    Console.WriteLine("Data arrived: "+receivedNum);
                }
            }
        }

        static object sync = new object(); //Kell a lockhoz

        static int receivedNum; //Közös változó.

        static void GenerateFunction() {
            canStart.WaitOne();
            while (true)
            {
                
                lock (sync)
                {
                    int rnd = Random.Shared.Next(0, 50); //Generál egy véletlen számot 0 és 50 között.
                    receivedNum = rnd; //Beállítja a közös változót, amit a monitor thread figyel.
                    valueGot.Set(); //Jelzi a fő threadnek, hogy megjött az adat.
                }
                System.Threading.Thread.Sleep(500);
            }
        }

        static void Monitor()
        {
            canStart.WaitOne();
            while (true)
            {
                System.Threading.Thread.Sleep(1000 * Random.Shared.Next(3)); //Random időközönként figyel, hogy változott-e a közös változó értéke.

                lock (sync)
                { //Kell a lock, hogy a jó értéket írja ki, ne egy köztes állapotot.
                    Console.WriteLine("Analyzing value: " + receivedNum);
                    System.Threading.Thread.Sleep(10);
                }
            }
        }
    }
}
