Bueno ... puede arrebatar todos los contadores de semáforos en el hilo principal hacia atrás con el fin de bloques cuando el número es 0, en lugar de no-cero.
MODIFICADO: Aquí asumió 3 cosas:
- Mientras que el programa se está ejecutando, un nuevo trabajo de descarga puede comenzar en cualquier momento.
- Al salir del programa, no habrá más descargas nuevas que necesiten atención.
- Al salir del programa, tiene que esperar a que los todos los archivos para terminar la descarga
Así que aquí está mi solución, revisada:
Inicializa el semáforo con un contador lo suficientemente grande como para que nunca se pulsa el máximo (que podría ser simplemente 100 o 10 dependiendo de su situación):
var maxDownloads = 1000;
_semaphore = new Semaphore(0, maxDownloads);
Luego, en cada descarga, comienza con WaitOne() antes de iniciar la descarga de modo que en caso de salir del programa, sin descargas pueden empezar .
if (_semaphore.WaitOne())
/* proceeds with downloads */
else
/* we're terminating */
A continuación, en la terminación de descarga, liberar un contador (si hubiéramos adquirido uno):
finally { _semaphore.Release(1); }
y luego en el evento "Salir", consumen todos los contadores en el semáforo:
for (var i = 0; i < maxDownloads; i++)
_semaphore.WaitOne();
// all downloads are finished by this point.
...
bloqueo en este olor divertido –
@Ori: ¿Por qué? MSDN dice que es una forma común de hacerlo: http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.71).aspx – mpen
@Mark: tenga mucho cuidado con el uso de documentación antigua. Su página era la versión de .NET 1.1, cuando no sabíamos mejor. Ver http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx. –