title: Precise alternative to Thread.Sleep
body: <p>I have a method Limit() which counts a bandwidth passed thought some channel in certain time and limits by using Thread.Sleep() it  (if bandwidth limit is reached).
  Method itself produces proper ( in my opinion results ) but Thread.Sleep doesn't ( due to multithreaded CPU usage ) because i have proper "millisecondsToWait" but speed check afterwards is far from limitation i've passed. </p>
  
  <p><strong>Is there a way to make limitation more precise ?</strong></p>
  
  <p>Limiter Class</p>
  
  <pre><code>    private readonly int m_maxSpeedInKbps;
      public Limiter(int maxSpeedInKbps)
      {
          m_maxSpeedInKbps = maxSpeedInKbps;
      }
  
      public int Limit(DateTime startOfCycleDateTime, long writtenInBytes)
      {
          if (m_maxSpeedInKbps &gt; 0)
          {
              double totalMilliseconds = DateTime.Now.Subtract(startOfCycleDateTime).TotalMilliseconds;
              int currentSpeedInKbps = (int)((writtenInBytes / totalMilliseconds));
              if (currentSpeedInKbps - m_maxSpeedInKbps &gt; 0)
              {
                  double delta = (double)currentSpeedInKbps / m_maxSpeedInKbps;
                  int millisecondsToWait = (int)((totalMilliseconds * delta) - totalMilliseconds);
                  if (millisecondsToWait &gt; 0)
                  {
                      Thread.Sleep(millisecondsToWait);
                      return millisecondsToWait;
                  }
              }
          }
  
          return 0;
      }
  </code></pre>
  
  <p>Test Class which always fails in large delta</p>
  
  <pre><code>[TestMethod]
  public void ATest()
  {
      List&lt;File&gt; files = new List&lt;File&gt;();
      for (int i = 0; i &lt; 1; i++)
      {
          files.Add(new File(i + 1, 100));
      }
  
      const int maxSpeedInKbps = 1024; // 1MBps
      Limiter limiter = new Limiter(maxSpeedInKbps);
  
      DateTime startDateTime = DateTime.Now;
      Parallel.ForEach(files, new ParallelOptions {MaxDegreeOfParallelism = 5}, file =&gt;
      {
          DateTime currentFileStartTime = DateTime.Now;
          Thread.Sleep(5);
          limiter.Limit(currentFileStartTime, file.Blocks * Block.Size);
      });
  
      long roundOfWriteInKB = (files.Sum(i =&gt; i.Blocks.Count) * Block.Size) / 1024;
      int currentSpeedInKbps = (int) (roundOfWriteInKB/DateTime.Now.Subtract(startDateTime).TotalMilliseconds*1000);
  
      Assert.AreEqual(maxSpeedInKbps, currentSpeedInKbps, string.Format("maxSpeedInKbps {0} currentSpeedInKbps {1}", maxSpeedInKbps, currentSpeedInKbps));
  } 
  </code></pre>