2010-12-06 11 views
5

tengo (quiero) para ejecutar una solicitud de búsqueda a varias fuentes. Ahora he hecho algunos subprocesos múltiples en el pasado, pero todo fue fuego y olvido.Solicitud multiproceso/asincrónica y espere a que se hayan completado y luego procese los resultados

Ahora lo que quiero hacer es girar 3 solicitudes idénticas en 3 objetos diferentes, esperar hasta que estén 'hechas' (y eso me da la primera pregunta: ¿cómo dicen 'ya terminé'? , y luego recoger todos los datos thet've me envió

Así que en pseudo código que tengo esta interfaz:.

interface ISearch 
    SearchResult SearchForContent(SearchCriteria criteria) 

Así que en código que crea los servicios de búsqueda de tres:

ISearch s1 = new SearchLocal(); 
ISearch s2 = new SearchThere(); 
ISearch s3 = new SearchHere(); 

Y el n llamar SearchForContent(SearchCriteria criteria) en los tres de ellos, de una manera multihreaded/asíncrono

y todos ellos vienen de nuevo a mí con su SearchResult y después de que todos se hacen, i Proceso SearchResult sus objetos.

Espero que estas líneas de texto tipode hace que se obtiene lo que está en mi cabeza :)

estoy trabajando en un proyecto # ASP.Net 3.5 C.

+2

Es más fácil de hacer este tipo de cosas con objetos 'Task'. Se introdujeron en .NET 4, pero se han incluido en la biblioteca Rx (no compatible, use-at-your-own-risk) (http://msdn.microsoft.com/en-us/devlabs/ee794896. aspx). ¿Utiliza Rx como opción o necesita una solución puramente .NET 3.5? –

+0

No, lo siento, necesito una solución puramente 3.5. – Michel

+0

Gahh solo ahora leyendo el comentario sobre 3.5, supongo que las tareas no funcionarán para usted, entonces – BrokenGlass

Respuesta

6

Crear AutoResetEvent y pasarlos a WaitHandle.WaitAll()

Hay un ejemplo here.

Básicamente:

1) Se crea una AutoResetEvent para cada búsqueda y pasan false a su constructor.

2) Crear los hilos y correr de búsqueda para cada uno y al final, lo llaman Set en el AutoResetEvent en el bloque finalmente. Es muy importante que llamar al Set se haga dentro del bloque finally; de lo contrario, WaitAll() estará esperando indefinidamente.

3) En el código justo después de haber engendrado los hilos, llame al WaitHandle.WaitAll() y pase todos esos AutoResetEvent a él. Este código va a espere hasta que todo haya terminado.

+0

¿Es posible ser un poco más preciso, no creo que obtenga esto ... – Michel

+0

He actualizado. Hay otro ejemplo aquí. http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.autoresetevent(VS.95).aspx – Aliostad

+0

@Aliostad, tendrá que modificar sus implementaciones 'ISearch' para aceptar' AutoResetEvents '(o el manejador de espera que elijas) en sus constructores. Además, deberá agregar una forma de acceder a los resultados de forma asincrónica (por ejemplo, 'ISearch.SearchResults {get;}'). –

0

Haga un IEnumerable<ISearch>, y esos artículos, y haga .AsParallel().ForAll(...) en él.

Edición

ParaTodos no proporcione resultados, si se puede cambiar ISearch, darle una propiedad de los resultados, a continuación, una vez que el ParaTodos se hace se puede ver en los resultados a través de la interfaz IEnumerable.

Y sí, lo siento, esto es 4.0.

+1

.NET 3.5, sin suerte. –

+1

ForAll no devolverá los resultados. –

2

Utilización de tareas que podría hacer una continuación de esta manera:

 Task[] t = new Task[2]; 
     t[0] = Task.Factory.StartNew(() => { Thread.Sleep(1000); }); 
     t[1] = Task.Factory.StartNew(() => { Thread.Sleep(2000); }); 

     Task.Factory.ContinueWhenAll(t, myTasks => { Console.WriteLine("All done!"); }); 
+0

es de hecho 3,5, pero gracias por el código de todos modos, nunca se sabe cuándo lo necesitaré en un proyecto de 4.0. – Michel

Cuestiones relacionadas