Pregunta

¿Hay un generador de números secuenciales a nivel de sistema administrado? DateTime.Now.Ticks no lo harán porque las operaciones que estoy haciendo a veces se producen más de una vez por garrapata.


Aclaraciones Requisito:

  • Proceso agnóstico -. No hay realmente sólo un proceso que se accede a este
  • El rendimiento es crítico! Esto se utiliza para el registro de impresiones sobre un servidor de anuncios, que puede alcanzar 1k / sec

Se tendría que ser uno de los siguientes:

  • Un número secuencial de 4 bytes que restablece cada tic-tac
  • A 12-byte número secuencial - la adición de esencialmente 4 bytes de granularidad a un DateTime
¿Fue útil?

Solución

Nada que están destinados para esto, pero se puede usar System.Diagnostics.PerformanceCounter. También es posible usar el Registro, pero se necesitaría para serializar el acceso de lectura / escritura al otro lado de los procesos.

System.Diagnostics.PerformanceCounter pc 
    = new System.Diagnostics.PerformanceCounter("SeqCounter", "SeqInstance");
long myVal=pc.Increment();

Editar

Cuanto más pienso en ello, creo que esto podría ser una buena solución. Incremento aumentará el contador en 1 a través de una operación atómica que debe trabajar al otro lado de todos los procesos en un sistema.

Editar

Sobre la base de sus ediciones, yo no recomendaría el uso de un contador de rendimiento. Un contador de rendimiento era una forma de cordinate al otro lado de múltiples procesos. No estoy seguro de cómo se codifica el IMPLEMENTACIÓN interno.

¿Por qué no puedes usar una variable estática y se incrementará? Su va a tener que bloquear algo si quieres que esto sea multi-hilo.

System.Threading.Interlocked.Increment

Para su información:. Si se utiliza la versión larga en un sistema de 32 bits no será nessecarilly de subprocesos


Edición para mostrar el IMPLEMENTACIÓN utilicé (DS):

public static class Int32Sequencer
{
    private static Int32 lastSequence = Int32.MinValue;
    private static Object lockObject = new Object();
    public static Int32 GetNextSequence()
    {
        lock (lockObject)
        {
            unchecked { lastSequence++; }
            return lastSequence;
        }
    }
}

Otros consejos

Un GUID es lo más cerca que vas a conseguir, pero los que son "única" y no necesariamente secuencial. Si realmente quiere secuencial a través de múltiples procesos a nivel del sistema, es probable que tenga a liar.

EDIT:

Ok, por lo que desde sus nuevas necesidades, voy a asumir:

  1. Sólo un proceso que tiene que hacer el trabajo
  2. está anexando a una base de datos

Así que aquí es lo que yo recomendaría:

  1. En el proceso de puesta en marcha, consultar la base de datos para el último valor (mayor) (0 si no existe).
  2. Utilice un largo sencillo y de incremento para cada fila DB. Usted va a querer insertar en lotes debido a su alta velocidad de datos.

Eso debería hacerlo. Mantenlo simple. Esto no tiene cerraduras, una ligera (insignificante) golpeó en el arranque, y los números secuenciales en su base de datos. Este algoritmo es también proceso de agnotic siempre y sólo tiene un proceso de ejecutarlo.

Creo que lo más parecido es un GUID, que como estoy seguro de que está consciente es a lo sumo parcialmente secuencial.

Hay un artículo por aquí que le da algunos detalles para el servidor SQL: secuenciales de GUID en SQL servidor Esta técnica se utiliza para minimizar divisiones de página debido a la aleatoriedad de GUID de. Tal vez este enlace le dará algunos consejos o ideas.

Creo que necesitamos saber un poco más acerca de lo que busca. Puede aclarar su pregunta un poco. En particular, hace el servicio ...

  • necesidad de trabajar en todos los procesos, un proceso, o un usuario en particular?
  • ¿Deben los números de ser único o simplemente secuencial?

En base a su pregunta parece que hay un par de cosas diferentes que usted puede estar buscando.

¿Necesita un grupo secuencial de los números a través de todos los procesos en el sistema

Que yo sepa, no existe tal servicio. Uno debería ser bastante fácil de escribir, pero conseguir que funcione en todos los procesos es difícil.

¿Necesita un grupo secuencial único de números a través de todos los procesos en el sistema

Una pequeña variación en la primera pregunta. Tal servicio no existe, ya que sería imposible de implementar. No hay manera de garantizar un número secuencial único que utiliza los tipos de datos incorporados simplemente porque el valor con el tiempo de desbordamiento y te dejan con un número duplicado.

¿Necesita un método para obtener valores únicos en el sistema

Como muchos otros usuarios han mencionado la mejor opción es una instancia System.Guid. Puede crear uno nuevo utilizando Guid.NewGuid (). Para casi todos los fines de que puedan ser consideradas únicas, pero no son secuenciales.

Me gusta la opción de base de datos, simplemente por seguridad. Asegúrese de instalar un servidor SQL con monstruo adjudicar de ancho de banda entre los servidores con memoria suficiente sin embargo. Un sistema similar a esto se llevó a cabo en la primera empresa que he trabajado para (Antes de que incluso se convirtió en un programador) y era muy poco fiable. Es posible que la batalla para escalar esto.

Otra opción sería la de implementar una función de Singleton en su código ... proporciona un único dominio de aplicación se llama ella. Puede ser un poco más rápido que hacer un viaje de base de datos. Sin embargo, si se van a registrar este material a la base de datos de todas formas .... ¿Qué pasa con la combinación de los dos ... Ejecutar un producto único para la velocidad y luego escribir en la base de datos cuando los recursos lo permitan.

Una vez más, si el requisito secuencial no es tan fuerte, un GUID sería la mejor opción.

No hay manera de conseguir una única serie secuencial sin bloquear. No importa cuál es el mecanismo que utiliza para asignar el siguiente valor - un contador de rendimiento, una variable estática, lo que sea -. Cuando dos hilos tanto necesitan el siguiente valor al mismo tiempo, uno tiene que esperar por otra

Lo primero que me gustaría hacer es escribir un programa de prueba que dio lugar a un gran número de hilos que cada pedido en repetidas ocasiones una función de incremento de bloqueo como el que se ha escrito Daniel Schaffer. Eso le permitirá encontrar el umbral donde su aplicación comienza a agitarse -., Donde se trata de pasar más tiempo esperando en Monitor.Enter de hacer cualquier otra cosa

Si esto resulta ser un problema - y yo apostaría que si los volúmenes que estamos hablando son reales, será - entonces usted debe hacer cada hilo mantener su propio contador secuencial, lo que se puede hacer marcando el campo de contador con el ThreadStaticAttribute. A continuación, puede generar identificadores únicos fuera de una combinación de ID de la rosca y el mostrador.

Este enfoque no funcionará si no se está usando un grupo de subprocesos (ya que el contador muere cuando el hilo al que pertenece lo hace). Y es probable que también quiere hacer parte conteo de inicio de la aplicación del compuesto ID, de modo que usted no tiene que escribir los contadores de rosca para el almacenamiento duradero. (Si no hace esto, cuando se reinicia el servidor los hilos comenzarían a generar contadores a cero de nuevo, y si su aplicación crea un hilo con el mismo ID que una instancia anterior, se obtendría identificadores duplicados.)

Esto obviamente no es trivial para escribir (o, más importante, la prueba), por lo que definitivamente recomiendo que demuestra que es necesario en primer lugar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top