Estoy usando marcas de tiempo para ordenar temporalmente cambios simultáneos en mi programa, y requiero que cada marca de tiempo de un cambio sea única. Sin embargo, descubrí que simplemente llamar a DateTime.Now
es insuficiente, ya que a menudo devolverá el mismo valor si se llama en sucesión rápida.¿Cómo asegurar que una marca de tiempo sea siempre única?
Tengo algunas ideas, pero nada me parece la mejor solución para esto. ¿Hay algún método que pueda escribir que garantice que cada llamada sucesiva produzca un único DateTime
?
¿Debo tal vez utilizar un tipo diferente para esto, tal vez una int larga? DateTime
tiene la ventaja obvia de ser fácilmente interpretable como un tiempo real, a diferencia de, por ejemplo, un contador incremental.
Actualización: Esto es lo que acabamos de codificación como una solución de compromiso simple que todavía me permite usar DateTime
como mi clave temporal, al tiempo que garantiza la unicidad cada vez que el método se llama:
private static long _lastTime; // records the 64-bit tick value of the last time
private static object _timeLock = new object();
internal static DateTime GetCurrentTime() {
lock (_timeLock) { // prevent concurrent access to ensure uniqueness
DateTime result = DateTime.UtcNow;
if (result.Ticks <= _lastTime)
result = new DateTime(_lastTime + 1);
_lastTime = result.Ticks;
return result;
}
}
Debido a que cada el valor tick es solo una 10 millonésima de segundo, este método solo introduce un obvio sesgo en el reloj cuando se lo llama del orden de 10 millones de veces por segundo (que, por cierto, es lo suficientemente eficiente para ejecutarse en), lo que significa que es perfectamente aceptable para mis propósitos
Aquí hay un código de prueba:
DateTime start = DateTime.UtcNow;
DateTime prev = Kernel.GetCurrentTime();
Debug.WriteLine("Start time : " + start.TimeOfDay);
Debug.WriteLine("Start value: " + prev.TimeOfDay);
for (int i = 0; i < 10000000; i++) {
var now = Kernel.GetCurrentTime();
Debug.Assert(now > prev); // no failures here!
prev = now;
}
DateTime end = DateTime.UtcNow;
Debug.WriteLine("End time: " + end.TimeOfDay);
Debug.WriteLine("End value: " + prev.TimeOfDay);
Debug.WriteLine("Skew: " + (prev - end));
Debug.WriteLine("GetCurrentTime test completed in: " + (end - start));
... y los resultados:
Start time: 15:44:07.3405024
Start value: 15:44:07.3405024
End time: 15:44:07.8355307
End value: 15:44:08.3417124
Skew: 00:00:00.5061817
GetCurrentTime test completed in: 00:00:00.4950283
Así, en otras palabras, en el medio segundo que genera 10 millones de únicas marcas de tiempo, y el resultado final solo fue adelantado en medio segundo. En aplicaciones del mundo real, el sesgo sería imperceptible.
¿La aplicación tiene varios subprocesos? ¿El significado puede dos hilos diferentes pedir una identificación al mismo tiempo? –
Sí ............ – devios1
¿Hay algún motivo por el que no pueda usar las guías? – juharr