Pregunta

Tengo un código de transferencia de archivos de alto rendimiento que he escrito en C # utilizando el modelo asíncrono Programación (APM) idioma (por ejemplo, BeginRead / EndRead). Este código lee un archivo de un disco local y lo escribe en una toma de corriente.

Para un mejor rendimiento en el hardware moderno, es importante tener más de una operación de E / S pendientes en vuelo siempre que sea posible. Por lo tanto, he puesto varias operaciones BeginRead en el archivo, entonces cuando uno completa, me llaman un BeginSend en el zócalo, y cuando lo hacen, que completa otra BeginRead en el archivo. Los detalles son un poco más complicado que eso, pero por el alto nivel que es la idea.

Tengo el código de trabajo a base de APM, pero es muy difícil de seguir y probablemente tiene errores de concurrencia sutiles. Me encanta usar TPL para este lugar. Me Task.Factory.FromAsync figurado sería sólo de hacerlo, pero hay una trampa.

Todas las muestras de E / S que he visto (muy especialmente la clase StreamExtensions en el paralelo Extensiones Extras) asume uno leía seguido de uno de escritura. Esto no va a realizar la necesidad manera en que yo.

No se puede utilizar algo tan simple como Parallel.ForEach o la extensión Task.Factory.Iterate extras porque las tareas asíncronas de E / S no pasan mucho tiempo en un subproceso de trabajo, de modo paralelo solo se pone en marcha otra tarea, dando como resultado potencialmente decenas o cientos de pendiente de operaciones de E / S; ¡demasiado! Puede resolver esto Waiting en sus tareas, pero que hace que la creación de un identificador de evento (un objeto de núcleo), y una espera de bloqueo en un identificador de tarea de espera, lo que inmoviliza un subproceso de trabajo. Mi aplicación basada en APM evita ambas cosas.

He estado jugando un poco con diferentes maneras de mantener varias operaciones de lectura / escritura en vuelo, y he conseguido hacerlo a través de las continuaciones que llaman a un método que crea otra tarea, pero se siente incómodo, y definitivamente doesn' t sentir como TPL idiomática.

¿Alguien más ha intentado resolver un problema de este tipo con el TPL? ¿Alguna sugerencia?

¿Fue útil?

Solución

Si usted está preocupado por demasiadas hebras, sólo puede conjunto ParallelOptions.MaxDegreeOfParallelism a un número aceptable en su llamada a Parallel.ForEach.

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