title: Display a timer in Blazor
body: <p>I am attempting to display a countdown timer in a server-side Blazor app.  My code is in both F# and C#.  The code somewhat works, but the timer never stops as intended, and the timer display sporadically does not render all of the numbers. This is my first attempt at a Blazor server-side app. I am not sure if the problem is an async issue, timer issue, or rendering issue.  </p>
  
  <p>Here's my code:</p>
  
  <p>F# </p>
  
  <pre><code>let private setTimer countDown timeEvent =
  
      let timer = new Timer(float countDown * float 1000)
      let mutable time = 0
  
      time &lt;- countDown
  
      timer.Elapsed.Add(fun arg -&gt;
          time &lt;- time - 1
          if time = 0
          then 
              timer.Stop()
              timer.Dispose()
          else
              ()
          timeEvent arg
      )
  
      timer.AutoReset &lt;- true
      timer.Start()
  
  let setTimerAsync countDown timeEvent = async{
      setTimer countDown timeEvent
      do! Async.Sleep (countDown * 1000)
  }
  
  type Timer (countDown) =
  
      member val CountDown : int = countDown with get,set
  
      member this.SetTimeAsTask (timeEvent) =
          setTimerAsync countDown timeEvent |&gt; Async.StartAsTask
  </code></pre>
  
  <p>C# / Blazor</p>
  
  <pre><code>@page "/CountDown"
  @using System.Timers
  @using ClientTImer
  @using Microsoft.FSharp.Core
  
  &lt;h3&gt;Count Down&lt;/h3&gt;
  &lt;p&gt;
      Task: @task &lt;br /&gt;
      Status: @status
  &lt;/p&gt;
  &lt;p&gt;
      Timer: @time
  &lt;/p&gt;
  
  @code {
      string task = "";
      string status = "";
      int time = 5;
  
      protected override async Task OnInitializedAsync()
      {
  
          // Initial task and status
          task = "First Task";
          status = "Status One";
  
          Action&lt;System.Timers.ElapsedEventArgs&gt; timeEvent =
              t =&gt;
              {
                  UpdateTime().Wait();
              };
  
          var func = FuncConvert.ToFSharpFunc(timeEvent);
  
          await new ClientTImer.Timer(time).SetTimeAsTask(func);
  
          // Update task and status
          task = "Second Task";
          status = "Status Two";
          await new ClientTImer.Timer(time).SetTimeAsTask(func);
  
          // Update task and status
          task = "Third Task";
          status = "Status Three";
  
      }
  
      public async Task UpdateTime()
      {
          await InvokeAsync(() =&gt;
          {
              time--;
              StateHasChanged();
          });
      }
  
  }
  </code></pre>