title: Problem with receiving suitable value with action event in c#
body: <p>I have to prepare a task for my study, where I have to prepare a custom class Timer, with Name and NumberOfTicks regarding to the instructions.
  You need to implement the Timer class for simulating a countdown clock. The Timer has the ability to send out messages with the information about Started, Tick and Stopped events to other types subscribed to the events. Don't use the .NET System.Timer classes for the Timer implementation. The Timer class should have the following functionality:</p>
  <p>When an object of the Timer class is constructed it has to be assigned:
  Name (not a null or an empty string, otherwise the exception ArgumentException should be thrown);
  Number of ticks (the number has to be greater than 0; otherwise, the exception ArgumentException should be thrown).
  After the Timer has been created it should be called to Run. In response to Run, the Timer fires the Started event. The event should contain the information about the Timer's Name and the Number of ticks to be fired.
  After firing the Started event, the Timer starts firing Tick events with the information abount the Timer's name and the number of ticks left to fire. There should be delays between the Tick events. To emulate the delays between the Tick events, it is recommended to use the Thread.Sleep method.
  After all Tick events have been fired, the Timer has to fire Stopped event, the event should contain the Timer's name information.
  You need to complete the implementation of the CountDownNotifier class. This class consumes events from the Timer. The implementation logic must check that when the object of CountDownNotifier class is created, the null is not passed as a parameter insted of the Timer object.</p>
  <p>Provide the implementation of the Factory methods to create objects of the Timer and CountDownNotifier classes.</p>
  <p>Code with my Custom Timer class</p>
  <pre><code>        public event Action&lt;string, int&gt; Tick;
  
          public int NumberOfTicks
          {
              get =&gt; this.numberOfTicks;
              set
              {
                  this.numberOfTicks = value;
  
                  if (this.numberOfTicks &lt;= 0)
                  {
                      throw new ArgumentException(nameof(this.numberOfTicks));
                  }
              }
          }
  
          public virtual void OnTick(Action&lt;string, int&gt; tickDelegate)
          {
              this.Tick = tickDelegate;
              tickDelegate?.Invoke(this.Name, this.NumberOfTicks - 1);
          }
  </code></pre>
  <p>There is my code with my class CountDownNotifier, apart from that code there is a constructor with timer parameter</p>
  <pre><code>        /// &lt;summary&gt;
          /// Initializes event handlers.
          /// &lt;/summary&gt;
          /// &lt;param name=&quot;startHandler&quot;&gt;Represents a Start event handler. Can be null.&lt;/param&gt;
          /// &lt;param name=&quot;stopHandler&quot;&gt;Represents a Stop event handler. Can be null.&lt;/param&gt;
          /// &lt;param name=&quot;tickHandler&quot;&gt;Represents a Tick event handler. Can be null.&lt;/param&gt;
          public void Init(Action&lt;string, int&gt; startDelegate, Action&lt;string&gt; stopDelegate, 
             Action&lt;string, int&gt; tickDelegate)
          {
              this.timer.OnStarted(startDelegate);
              this.timer.OnStopped(stopDelegate);
              this.timer.OnTick(tickDelegate);
          }
  
          /// &lt;summary&gt;
          /// Starts timer.
          /// &lt;/summary&gt;
          public void Run()
          {
              this.timer.OnStarted();
          }
  </code></pre>
  <p>Below is a unit test. Result which I have received is equal to the second parameter, but I am expecting lower by 1, for example for the first test case I want to receive result equal to 9. Unit tests can not be changed. my task is to prepare the Timer class in such a way that unit tests will pass, unfortunately this one does not pass in my solution.</p>
  <pre><code>        [TestCase(&quot;pie&quot;, 10)]
          [TestCase(&quot;cookies&quot;, 5)]
          [TestCase(&quot;pizza&quot;, 1)]
          public void Run_ValidTimer_AllEventsWorkAsExpected(string name, int totalTicks)
          {
              var timer = this.timerFactory.CreateTimer(name, totalTicks);
              var notifier = this.countDownNotifierFactory.CreateNotifierForTimer(timer);
  
              void TimerStarted(string timerName, int ticks)
              {
                  Assert.AreEqual(name, timerName);
                  Assert.AreEqual(totalTicks, ticks);
                  Console.WriteLine($&quot;Start timer '{timerName}', total {ticks} ticks&quot;);
              }
  
              void TimerStopped(string timerName)
              {
                  Assert.AreEqual(name, timerName);
                  Console.WriteLine($&quot;Stop timer '{timerName}'&quot;);
              }
  
              var remainsTicks = totalTicks;
  
              void TimerTick(string timerName, int ticks)
              {
                  remainsTicks -= 1;
                  Assert.AreEqual(name, timerName);
                  Assert.AreEqual(remainsTicks, ticks);
                  Console.WriteLine($&quot;Timer '{timerName}', remains {ticks} ticks&quot;);
              }
  
              notifier.Init(TimerStarted, TimerStopped, TimerTick);
              notifier.Run();
  
              Assert.AreEqual(0, remainsTicks - 1);
          }
  </code></pre>