Sugerencias para hacer asíncrono de E / S con la tarea paralela Biblioteca
-
26-09-2019 - |
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 Wait
ing 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?
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
.