I am trying to learn C#. Please tell me if the following code respects coding standards and naming conventions because I want to write beautiful code. The purpose of this program was to help me understand different concepts that I've learned in the last few days but I was having difficulties thoroughly understanding them (especially events and delegates). Please show me what you would change by exemplifying, not just by recommending, because I have a harder time understanding phrases than code.For example, I've been told to use async/await and the TPL. I've made a couple simple programs with them, yet I still dont know how I would apply the concepts here. I'll keep trying while waiting for an answer from you, I'll be reading the chapters from here in the next few hours.Also, I've been told I should have used Action. I want to use Actions because I like Action and Func, yet I dont know where should I use Action.TProgram.cs:#define DEBUG#define TRACEusing System;using System.Diagnostics;using System.Text;using System.Threading;namespace LearnEventsAndOthers{    class Program    {        private static void OnTicked(object sender, TickingEventArgs e)        {            Console.WriteLine(Event triggered in object {0} at tick {1}, ((Metronom)sender).Id, e.TickCount);        }        static int Main(string[] args)        {            #region Standard Code - Init            Console.InputEncoding = Console.OutputEncoding = Encoding.UTF8;            Console.SetWindowSize(160, 56);            Console.BufferHeight = 9000;            Console.BufferWidth = 300;#if DEBUG            Console.WriteLine(The program is running in #DEBUG mode.);#endif#if TRACE            Console.WriteLine(The program is running in #TRACE mode.);#endif            #endregion            // Creating objects and testing overridden functions Equals and GetHashCode...            Metronom m = new Metronom();            Metronom n = new Metronom();            Trace.Listeners.Add(new TextWriterTraceListener(System.IO.File.CreateText(TraceInfo.txt)));            Trace.AutoFlush = true;            Debug.Indent();            Debug.WriteLineIf(!m.Equals(n), string.Format(Objects n and m have been created and they have different IDs: {0} vs {1}, m.GetHashCode(), n.GetHashCode()));            Debug.Assert(!m.Equals(n), Objects n and m have been created but they are equal! This shouldn't happen.);            // Testing event subscription...            m.TickedEvent += OnTicked;            n.TickedEvent += OnTicked;            // Testing destructors...            Console.WriteLine(Environment.NewLine + Press any key to destroy the objects! + Environment.NewLine);            Console.ReadKey();            m.RequestStop();            Console.WriteLine(Environment.NewLine + The first object was destroyed. Waiting 5 seconds before destroying the second...);            Thread.Sleep(5000);            n.RequestStop();            #region Standard Code - Exit            Console.WriteLine(\nPress <enter> to exit!);            Console.ReadLine();            return 0;            #endregion        }    }}Metronom.cs:#define DEBUG#define TRACEusing System;using System.Diagnostics;using System.Threading;namespace LearnEventsAndOthers{    public class TickingEventArgs : EventArgs    {        public long TickCount { get; set; }    }    public class Metronom    {        public event EventHandler<TickingEventArgs> TickedEvent;        public Guid Id { get; private set; }        public int RandomStop { get; private set; } // Used to trigger the TickedEvent at random time spans.        protected internal const int SpeedModifier = 17777777;  // Used to control the speed at which events are triggered. Higher means slower.        // Why did I make it protected internal? I really wanted to use the access modifier internal.        private readonly Thread _t;        private volatile bool _shouldStop;        public Metronom()        {            this.Id = Guid.NewGuid();            checked            {                int hashCode = Math.Abs(this.GetHashCode());                while (hashCode > SpeedModifier)                    hashCode -= SpeedModifier;                RandomStop = hashCode;            }            _t = new Thread(Clock) { IsBackground = true };            _t.Start();            Debug.WriteLine(Object initialized with GUID HashCode  + this.GetHashCode());        }        ~Metronom()        {            _t.Join();            Debug.WriteLineIf(_t.IsAlive == false, string.Format(Thread from object {0} has been stopped., this.Id));            Debug.Assert(_t.IsAlive == false, string.Format(Thread from object {0} is still running., this.Id));        }        protected virtual void OnTickedEvent(long l)        {            EventHandler<TickingEventArgs> handler = TickedEvent;            if (handler != null) handler(this, new TickingEventArgs() { TickCount = l });        }        public void RequestStop()        {            _shouldStop = true;        }        private void Clock()        {            Stopwatch c = new Stopwatch();            c.Start();            Debug.WriteLineIf(_t.IsAlive, string.Format(Thread from object {0} has gone LIVE!, this.Id));            while (!_shouldStop)            {                long l = c.ElapsedTicks;                if ((l % this.RandomStop) == 0)                {                    OnTickedEvent(l);                }            }        }        public override bool Equals(object obj)        {            return obj is Metronom && (((Metronom)obj).Id.Equals(Id));        }        public override sealed int GetHashCode()        {            return Id.GetHashCode();        }    }}
C# program that uses events
c#;multithreading;delegates