title: C# await Task.Delay(1000); only takes 640ms to return
body: <p>So, this is simple to explain, but I have searched and cannot find anyone with the same issue. My problem originated in a long-term periodic task which was running more frequently than I wanted. It seems every Task.Delay() I create and await returns in about 65% of the delay I specified in ms. </p>
  
  <p>The problem boiled down to the following line of code returning in roughly 640-660ms (According to visual studio. I set a breakpoint on this line of code and the one following it, and it said that's how long had passed):</p>
  
  <pre><code>await Task.Delay(1000); 
  </code></pre>
  
  <p>On two other machines, the IDENTICAL code base runs just fine. Not only this simple statement above, but the periodic tasks as well. Is there a setting somewhere that would affect Task.Delay(int millisecondsDelay)? Tick type, clock speed, anything, system clock??? I am at a loss...</p>
  
  <p>EDIT:</p>
  
  <p>In the snippet below, EtMilliseconds is anywhere from 130-140ms, which is the same approx. 65% of expected duration seen above. Never anything outside that (besides the first time into the while() which is irrelevant).</p>
  
  <pre><code>Long EtMilliseconds;
  Stopwatch etWatch = new Stopwatch();
  etWatch.Restart();
  
  while (true)
  {
    EtMilliseconds = etWatch.ElapsedMilliseconds;
    taskDelay = Task.Delay(200);
    etWatch.Restart();
    await taskDelay;
  }
  </code></pre>
  
  <p>EDIT 2:</p>
  
  <p>The following code causes EtMilliseconds to be once again 131ms or so. Using Thread.Sleep seems to have no effect...</p>
  
  <pre><code>public partial class MainWindow : Window
  {
      public MainWindow()
      {
          InitializeComponent();
      }
  
      private void button_Click(object sender, RoutedEventArgs e)
      {
          long EtMilliseconds;
          Stopwatch etWatch = new Stopwatch();
          etWatch.Restart();
  
          while (true)
          {
              EtMilliseconds = etWatch.ElapsedMilliseconds;
              label.Content = EtMilliseconds.ToString();
              etWatch.Restart();
              Thread.Sleep(200);
          }
      }
  }
  </code></pre>
  
  <p>This snippet is the same but uses Task.Delay(200). This one updates the GUI label correctly (the Thread.Sleep does not) and it is either 131 or 140ms. Always...</p>
  
  <pre><code>public partial class MainWindow : Window
  {
      public MainWindow()
      {
          InitializeComponent();
      }
  
      private async void button_Click(object sender, RoutedEventArgs e)
      {
          Task taskDelay;
          long EtMilliseconds;
          Stopwatch etWatch = new Stopwatch();
          etWatch.Restart();
  
          while (true)
          {
              EtMilliseconds = etWatch.ElapsedMilliseconds;
              label.Content = EtMilliseconds.ToString();
              taskDelay = Task.Delay(200);
              etWatch.Restart();
              await taskDelay;
          }
  
      }
  }
  </code></pre>
  
  <p>EDIT 3:</p>
  
  <p>Using DispatcherTimer instead, I still get approx 130ms from my Stopwatch.ElapsedMilliseconds... BUT here's the strange thing. If I also update a display of DateTime.Now(), they increment by just about 200ms (or slightly more), which is what I would expect. What the?!?!
  <a href="https://i.stack.imgur.com/QOMmA.png" rel="noreferrer"><img src="https://i.stack.imgur.com/QOMmA.png" alt="enter image description here"></a></p>
  
  <pre><code>public partial class MainWindow : Window
  {
  
      public long etMilliseconds;
      public Stopwatch etWatch;
  
      public MainWindow()
      {
          InitializeComponent();
          this.DataContext = this;
      }
  
      //  System.Windows.Threading.DispatcherTimer.Tick handler
      //
      //  Updates the current seconds display and calls
      //  InvalidateRequerySuggested on the CommandManager to force 
      //  the Command to raise the CanExecuteChanged event.
      private void dispatcherTimer_Tick(object sender, EventArgs e)
      {
          // Updating the Label which displays the current second
          tBoxCurrTime.Text += DateTime.Now.ToString("yyyy_MMM_dd-hh:mm:ss.fff_tt") + "\n";
          tBoxMilliSecElapsed.Text += etWatch.ElapsedMilliseconds + "\n";
          etWatch.Restart();
  
          // Forcing the CommandManager to raise the RequerySuggested event
          CommandManager.InvalidateRequerySuggested();
      }
  
      private void button_Click(object sender, RoutedEventArgs e)
      {
          etWatch = new Stopwatch();
  
          //  DispatcherTimer setup
          DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
          dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
          dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
          dispatcherTimer.Start();
  
          etWatch.Restart();
      }
  }
  </code></pre>