2010-10-12 5 views
8

Estamos desarrollando una aplicación que lee continuamente datos de varios dispositivos de hardware externos. La velocidad de datos está entre 0.5MB - 10MB/seg, dependiendo de la configuración del hardware externo.Registro/registro rápido de datos en una hebra separada en C#

La lectura de los dispositivos externos se está realizando actualmente en un BackgroundWorker. Tratar de escribir los datos adquiridos en el disco con este mismo BackgroundWorker no parece ser una buena solución, entonces lo que queremos hacer es poner estos datos en cola para ser escritos en un archivo y tener otro hilo para delectar los datos y escribir en un archivo. Tenga en cuenta que habrá un solo productor y un solo consumidor para los datos.

Estamos pensando en utilizar una cola sincronizada para este fin. Pero pensamos que esta rueda ya debe haber sido inventada muchas veces, por lo que deberíamos pedirle a la comunidad de SO que nos dé su opinión.

Cualquier sugerencia o comentario sobre las cosas que debemos tener en cuenta sería apreciada.

Respuesta

2

Estoy bastante seguro de que su cola será más o menos bien. Pero asegúrese de utilizar un método eficiente de almacenamiento/recuperación de datos para no revisar su procedimiento de registro con asignación/desasignación de memoria. Me gustaría obtener un búfer de memoria preasignado y usarlo como una cola circular.

+0

Daniel, ¿crees que podemos usar las colas .NET para este propósito? Estamos pensando en utilizar ConcurrentQueue para almacenar punteros a los datos, pero preasignar la memoria para los datos antes de iniciar el registro. – SomethingBetter

+0

¿Qué tipo de datos registra? Structs, bytes simples, de hecho, mi pregunta es sobre eso si los datos se pueden serializar fácilmente en un paquete y leer de forma secuencial. Usted es de bajo nivel aquí, permanezca bajo nivel. –

-1

Ha intentado MSMQ

+0

Supongo que MSMQ no ayudará aquí, ya que tenemos demasiados datos, y MSMQ de alguna manera es API de alto nivel que consume CPU incluso cuando hace muy poco. –

2

puede ser necesario queing

por ejemplo. código

protected Queue<Byte[]> myQ; 
or 
protected Queue<Stream> myQ; 

//when u got the content try 
myQ.Enque(...); 

y utilizar otro hilo para hacer estallar la cola

// another thread 
protected void Loging(){ 
while(true){ 
    while(myQ.Count > 0){ 
    var content = myQ.Dequeue(); 
    // save content 
    } 
    System.Threading.Thread.Sleep(1000); 
} 
} 
+0

Bueno, en este caso, tendríamos que implementar mecanismos de bloqueo. El código anterior no parece ser seguro para subprocesos. – SomethingBetter

+0

.NET 4.0 tiene un ConcurrentQueue, que es seguro para subprocesos – SomethingBetter

+0

cuando usa Queue, no tiene que preocuparse por la seguridad de subprocesos. cuando desee obtener un elemento en la cola, solo tiene que quitar la cola. y no habrá ningún hilo cruzado procesando el mismo objeto – Bonshington

3

haría lo que una combinación de lo que hace el sr 888.

Básicamente en usted tiene 2 trabajadores de fondo, que lee desde el dispositivo de hardware. uno que escribe los datos en el disco.

Hardware fondo trabajador:
Añade mandriles en los datos en el hardware en el Queue<>. En el formato que lo tienes en.

escritura fondo trabajador
analiza los datos si es necesario y vuelca en el disco.

Una cosa a considerar aquí es, ¿es obtener la información del hardware en el disco lo más rápido posible?
En caso afirmativo, entonces tendría la prueba write brackground básicamente en un bucle con un sueño de 100ms o 10ms en el ciclo while con comprobación de si el que tiene datos.
Si no, entonces lo haría dormir una cantidad similar (suponiendo que la velocidad que obtiene de su hardware cambia periódicamente) y escribir solo en el disco cuando tiene alrededor de 50-60mb de datos. Consideraría hacerlo de esta manera porque los discos duros modernos pueden escribir aproximadamente 60mb pr segundos (este es un disco duro de escritorio, su empresa una vez podría ser mucho más rápida) y constantemente escribir datos en pequeños mandriles es una pérdida de ancho de banda IO.

+0

Gracias por la idea. Sí, creo que deberíamos almacenar los datos en búfer y escribirlos en grandes porciones. – SomethingBetter

0

que tienen una situación similar, En mi caso he utilizado una cola lockfree asíncrono con un objeto sincrónica LIFO Básicamente los hilos que escriben en la cola de establecer el objeto de sincronización en la LIFO, mientras que los otros hilos de los trabajadores 'reset la sincronización objeto en el LIFO Hemos arreglado el número de objetos de sincronización que son iguales a los hilos. La razón para usar un LIFO es mantener el mínimo número de subprocesos en ejecución y un mejor uso del sistema de caché.

Cuestiones relacionadas