使用 Delay(TimeSpan) 或 Thread.Sleep 在 VMware 中无法正常工作

Using Delay(TimeSpan) or Thread.Sleep doesn’t properly work in VMware

我将我的问题简化为这个例子:

[STAThread]
static void Main() {
   var t = Task.Run(async delegate {
      await Task.Delay(TimeSpan.FromSeconds(5));
      return "delayed action";
   });

   t.Wait();
   Console.WriteLine("Task t Status: {0}, Result: {1}", t.Status, t.Result);
}

虽然这在我的主机 PC 上运行正常,但它会在 运行 on VMware Workstation Player 15 上返回 "delayed action" 之前关闭并重新安装 Windows 10。没有错误。如果我把另一个 Console.WriteLine 放在开头,它会显示在 cmd 中。 我分配给 VMware 4 核和 6GB 内存,cpu 虚拟化关闭,3d 加速打开。我是否缺少某些依赖项,或者 VM 需要不同的配置?

我的目标是创建一系列需要随时间传播的 SendInput 函数。我什至尝试了一个有延迟选项的第三方“clicker”工具,它也有同样的问题。我必须将它设置为 30 毫秒才能获得 500 毫秒的点击次数,就好像大部分点击次数从未注册过一样。对我的代码执行相同操作在 VM 上不起作用,但在主机 PC 上运行正常。

很遗憾,我无法帮助您修复 VMWare 端,除了两个错误的想法:

  • 如果有任何东西通过线程直接到达主机 CPU,您可以尝试将其关闭。这对性能不利,但可能会避免线程(管理器)出现问题并在稍微不同的时钟上启动 OS 运行ning。

  • 我知道我有一个不同的方法你可以试试。对 Thread/Async 和类似延迟系统的依赖要少得多。一些可能稍微更健壮的东西,以对抗造成这种情况的任何原因。这种差异纯粹是偶然的——它开始是作为一个非常基本的速率限制系统的例子,在一个单独的线程中 运行:

    integer interval = 20;
    DateTime dueTime = DateTime.Now.AddMillisconds(interval);
    
    while(true){
      if(DateTime.Now >= dueTime){
        //insert code here
    
        //Update next dueTime
        dueTime = DateTime.Now.AddMillisconds(interval);
      }
      else{
        //Just yield to not tax out the CPU
        Thread.Sleep(1);
      }
    }

这个只使用线程机制来处理“闲置时的低 CPU 负载”部分。其他一切都基于希望更稳定的 DateTime 系统。

请注意,对短间隔的支持很差,即使是 20 毫秒也可能已经超出限制。 DateTime.Now() is not remotely as accurate as as the type can be precise,因此它仅适用于双位数或三位数间隔。 Delay 和 Sleep 确实支持毫秒精度。