用较小的时间尝试 Task.Delay。试图找出为什么会发生这种情况

Kan*_*bot 0 c# timedelay

试图了解如何使用 Task.Delay 我一直在做一系列简单的实验,我发现了以下内容。

首先我这样做了

static void Main(string[] args)
  {
     Console.WriteLine("Start");
     Task.Run(async () => {
                    Stopwatch sw = Stopwatch.StartNew();
                    await Task.Delay(2000);
                 //    for(int i=0;i<1000;i++)
                  //         await Task.Delay(2);
                     sw.Stop();
                    Console.WriteLine("Delay of {0}", sw.ElapsedMilliseconds);
                   //return sw.ElapsedMilliseconds;
                });

    Console.WriteLine("End of everything:");
    Console.ReadKey();

    }
Run Code Online (Sandbox Code Playgroud)

结果正如预期的那样延迟了 2 秒多一点。到目前为止,一切都很好!然后我注释了延迟线并取消注释了 for 循环。1000 次 2 毫秒必须给出 2 秒,对吗?错误的!这次用了15秒。

我稍后会对此发表评论,但只是为了进行比较,我这样做了。

    static void Main(string[] args)
    {
     Console.WriteLine("Start");
     Stopwatch sw = Stopwatch.StartNew();
     for (int i = 0; i < 1000; i++)
          Thread.Sleep(2);

//         Thread.Sleep(2000);
      sw.Stop();
      Console.WriteLine("Delay of {0}", sw.ElapsedMilliseconds);
      Console.WriteLine("End");

    }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我得到了更精确的 2 秒,而使用 for 循环则接近 2 秒。所以这不是发生的事情Thread.Sleep,而是只有发生的事情Task.Delay

现在,在文档中写道

该方法取决于系统时钟。这意味着,如果 millisecondsDelay 参数小于系统时钟的分辨率(在 Windows 系统上约为 15 毫秒),则时间延迟将大约等于系统时钟的分辨率。

就是这样!15秒理由!

我得到的另一个观察结果是,如果我将单个 Task.Delay 设置为 2000,我会得到 2 或 2.1 秒的一致延迟,但如果我将单个 Task.Delay 设置为 2(不是 for 循环),则延迟从运行到运行的时间会有很大差异。跑步。从 2 毫秒到 15 毫秒以及介于两者之间的所有时间

我的实验结束了。

我的问题是,有什么办法可以延迟几毫秒的时间吗?或者这是完全不可能的?任何可以扩大我对 Task.Delay 理解的评论将不胜感激。对带有小措施的 Task.Delay 行为的评论也将受到赞赏。请分享您的知识。

Hen*_*man 5

关于Thread.Sleep

睡眠间隔过后,线程就准备好运行。...请注意,就绪线程不能保证立即运行。因此,线程可能要等到睡眠间隔过去一段时间后才能运行。

关于Task.Delay

该方法取决于系统时钟。这意味着,如果 millisecondsDelay 参数小于系统时钟的分辨率(在 Windows 系统上约为 15 毫秒),则时间延迟将大约等于系统时钟的分辨率。

因此,这两种方法都不保证任何实时性,并且严重依赖于您的系统硬件和其他进程的负载。

请注意,例如,当线程池负担过重时,可能需要长达 500 毫秒的时间才能分配新线程。

Windows 并不是 RTOS,所有这一切都发生在时间片和 GC 运行的上下文中。