通过


Environment.TickCount 与 Windows 超时行为保持一致

在 Windows 上,Environment.TickCountEnvironment.TickCount64 已更新为与操作系统底层等待 API 中观察到的行为保持一致。 它们不再包括睡眠或休眠时间,作为测量已用时间的一部分。 此更改还使 Windows 行为与其他平台上看到的行为保持一致,并确保其更新频率与系统的基础中断计时器相同。 此更改允许在选择提高频率更新的应用中提高响应能力。

已引入的版本

.NET 11 预览版 1

以前的行为

以前,在 Windows 上, Environment.TickCount64 返回 Win32 GetTickCount64 API 的结果,该 API 以 10-16 毫秒(通常是 15.5 毫秒)的固定节奏进行更新,并包括系统在睡眠、休眠或其他低功率状态中花费的时间。

在其他平台上(如 Linux 和 macOS)上, Environment.TickCount64 更新频率与系统的基础中断计时器相同,并且仅包括系统被视为“唤醒”的时间。

在所有平台上, Environment.TickCount 返回截断的结果 Environment.TickCount64 并表现出相同的行为,但大约每 49 天就会溢出一次。

新行为

在 Windows 上, Environment.TickCount64 现在返回 Win32 QueryUnbiasedInterruptTime API 的结果。 此更改使 .NET API 的行为与操作系统基础等待 API 的行为一致。 它不再包括非活动时间,并以与系统基础中断定时器相同的频率进行更新。

在其他平台上, Environment.TickCount64 保留其行为,这与 Windows 上的新行为一致。

在所有平台上,Environment.TickCount 保持其实现,并复制 Environment.TickCount64 的行为。

破坏性变更的类型

此更改为行为更改

更改原因

Windows 在 Windows 8 和 Windows Server 2012 和更新版本中采取了类似的行为中断性变更,因此接受超时(如 SleepExWaitForMultipleObjectsEx)的 API 不再考虑非唤醒时间。 这导致与 .NET 的不一致,因为此类等待 API 经常与 Environment.TickCount64 一起使用,从而导致难以诊断的 bug,比如计时器意外触发。

此外,使用的基础 API GetTickCount64 不太精确,并且仅以固定分辨率进行更新。 如果 OS 的基础中断计时器发生频率更改,则不会调整此分辨率,这可能会导致为选择以较高优先级运行的应用执行其他工作。 该行为也与 macOS 和 Linux 等其他平台上看到的行为不一致。

此更改可确保与基础 OS 和跨平台保持一致。 它还可能导致应用中的响应能力更高,这些应用选择了更频繁的更新。

除非选择使用更高频率的中断时间,否则大多数代码不应遇到任何行为变化。 应用将继续以与以前相同的频率查看更新。 但是,如果更新频率是相关的,请确保超时参数传入的值符合代码预期,并且确保应用程序没有选择过高的更新频率。 (目前只能通过 P/Invoke API 完成此作。

某些代码可能会在计算机从睡眠状态或低功率状态唤醒后立即看到计时器不再触发。 如果此类时间是相关的,可以使用诸如 DateTime.UtcNow 之类的 API,确保可以始终包含这类时间。 此类代码可能必须考虑潜在的时钟调整。

在 Windows 上受此更改影响的代码很可能已受到 Linux 和 macOS 等其他平台上的相同方案的影响。

受影响的 API