Compartir a través de


Environment.TickCount se ha alineado con el comportamiento de timeout de Windows

En Windows, Environment.TickCount y Environment.TickCount64 se han actualizado para ser coherentes con el comportamiento visto en las API de espera subyacentes para el sistema operativo. Ya no incluyen tiempo de suspensión o hibernación como parte del tiempo transcurrido medido. Este cambio también hace que el comportamiento de Windows sea coherente con el comportamiento visto en otras plataformas y garantiza que se actualice con la misma frecuencia que el temporizador de interrupción subyacente para el sistema. Este cambio permite una mayor capacidad de respuesta en las aplicaciones que han optado por actualizar con mayor frecuencia.

Versión introducida

.NET 11 Preview 1

Comportamiento anterior

Anteriormente, en Windows, Environment.TickCount64 devolvía el resultado de la API GetTickCount64 de Win32, que se actualizaba a una cadencia fija de 10 a 16 ms (normalmente 15,5 ms) e incluía el tiempo que el sistema pasó en suspensión, hibernación u otros estados de baja potencia.

En otras plataformas (como Linux y macOS), Environment.TickCount64 se actualiza con la misma frecuencia que el temporizador de interrupción subyacente para el sistema y solo se incluye la hora en que el sistema se considera "despierto".

En todas las plataformas, Environment.TickCount devolvió el resultado truncado de Environment.TickCount64 y mostró un comportamiento idéntico, pero estaba sujeto a desbordamiento aproximadamente cada 49 días.

Nuevo comportamiento

En Windows, Environment.TickCount64 ahora devuelve el resultado de la API QueryUnbiasedInterruptTime de Win32. Este cambio pone en línea la API de .NET con el comportamiento usado en las API de espera subyacentes para el sistema operativo. Ya no incluye el tiempo no activo y se actualiza con la misma frecuencia que el temporizador de interrupción subyacente del sistema.

En otras plataformas, Environment.TickCount64 conserva su comportamiento, que es coherente con el nuevo comportamiento en Windows.

En todas las plataformas, Environment.TickCount mantiene su implementación y refleja el comportamiento de Environment.TickCount64.

Tipo de cambio disruptivo

Este es un cambio de comportamiento.

Motivo del cambio

Windows tomó un cambio importante de comportamiento similar en Windows 8 y Windows Server 2012 y versiones más recientes, de modo que las API que aceptan un tiempo de espera (como SleepEx y WaitForMultipleObjectsEx) ya no tienen en cuenta el tiempo de inactividad. Esto provocó una incoherencia con .NET, como las API de espera que se usan con frecuencia junto con Environment.TickCount64, lo que provoca errores difíciles de diagnosticar, como los temporizadores que se activan inesperadamente.

Además, la API subyacente que se usó, GetTickCount64, era menos precisa y solo se actualizaba en una resolución fija. Esta resolución no se ha ajustado si el temporizador de interrupción subyacente para el sistema operativo ha cambiado su frecuencia, lo que podría dar lugar a un trabajo adicional realizado para las aplicaciones que habían optado por ejecutarse con una prioridad más alta. El comportamiento también era incoherente con el comportamiento visto en otras plataformas, como macOS y Linux.

El cambio garantiza la coherencia con el sistema operativo subyacente y entre plataformas. También puede dar lugar a una mayor capacidad de respuesta en las aplicaciones que han optado por actualizaciones más frecuentes.

A menos que opte por tiempos de interrupción de mayor frecuencia, la mayoría del código no debe experimentar ningún cambio en el comportamiento. Las aplicaciones seguirán viendo actualizaciones con la misma frecuencia que antes. Sin embargo, si la frecuencia de actualización es relevante, asegúrese de que los tiempos de espera pasen un valor correcto que cumpla las expectativas del código o asegúrese de que la aplicación no opte por una frecuencia de actualización demasiado alta. (Esto solo se puede hacer a través de las API de P/Invoke hoy en día).

Es posible que algún código vea que los temporizadores ya no se activan inmediatamente después de que una máquina se despierte de un estado de suspensión o bajo consumo. Si ese tiempo es relevante, use api como DateTime.UtcNow para asegurarse de que ese tiempo siempre se puede incluir. Este código puede tener en cuenta los posibles ajustes del reloj.

Es probable que el código afectado por este cambio en Windows ya se vea afectado por el mismo escenario en otras plataformas, como Linux y macOS.

Las APIs afectadas