cómo hacer que el hilo de primer plano espere a que todos los hilos de fondo (secundarios) terminen en C#? Necesito obtener una lista de trabajos pendientes de la cola (base de datos), iniciar un nuevo hilo para ejecutar cada uno de ellos y finalmente esperar a que terminen todos los hilos hijo. cómo hacer eso en C#? Gracias por adelantado.cómo esperar a que finalicen todos los hilos de fondo (en C#)?
Respuesta
Considere el uso de ThreadPool. La mayoría de lo que quieres ya está hecho. Hay un example from Microsoft que hace prácticamente toda tu tarea. Reemplace "fibonacci" por "tarea de base de datos" y suena como su problema.
Leí este artículo hace unos minutos y estaba a punto de responder diciendo que esa es la solución que estaba buscando. gracias por la respuesta. – RKP
Puede almacenar cada hilo lanzado en una matriz. Luego, cuando necesite esperar a todos, llame al método Unir en cada hilo de una matriz en un bucle.
Thread child = new Thread(...);
Threads.Add(child);
child.Start()
...
foreach(Thread t in Threads)
{
t.Join();
}
HTH
Gracias por la respuesta. Creo que thread.Join método es bueno para un solo hilo o muy pocos número fijo de hilos. para varios hilos, creo que hay un método WaitAll, pero no pude encontrar un buen ejemplo de código para él. – RKP
@RKP: Esperar a que todos los hilos terminen es lo mismo que esperarlos a su vez, ¿no es así? Hay una función de winapi WaitForMultipleObjects, pero no es C#, aunque puedes usarla, pero no veo sentido. –
Esto es código incompleto, pero ManualResetEvent
obras para usted
var waitEvents = new List<ManualResetEvent>();
foreach (var action in actions)
{
var evt = new ManualResetEvent(false);
waitEvents.Add(evt);
ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, TimeoutCallback, state, 5000, true);
}
if (waitEvents.Count > 0)
WaitHandle.WaitAll(waitEvents.ToArray());
Gracias, pero ¿dónde se inicia el nuevo hilo para cada acción aquí en este código? ¿Es "5000" una configuración de tiempo de espera? – RKP
Mire aquí el código completo, acabo de copiar un poco de una de mis respuestas anteriores: http://stackoverflow.com/questions/3915017/image-url-validation-in-c/3915440#3915440 – danijels
Y sí, 5000 fue una configuración de tiempo de espera – danijels
Crear una estructura para realizar un seguimiento de sus subprocesos de trabajo
private struct WorkerThreadElement
{
public IAsyncResult WorkerThreadResult;
public AsyncActionExecution WorkerThread;
}
También es necesario realice un seguimiento del número total de subprocesos que se espera crear y la cantidad de subprocesos que tienen actualmente completado
private int _TotalThreads = 0;
private int _ThreadsHandled = 0;
private List<WorkerThreadElement> _WorkerThreadElements = new List<WorkerThreadElement>();
A continuación, cree un asa de autoreset para esperar la finalización del subproceso.
// The wait handle thread construct to signal the completion of this process
private EventWaitHandle _CompletedHandle = new AutoResetEvent(false);
También es necesario un delegado para crear nuevos temas - Hay varias formas de hacer esto, pero he elegido un delegado simple para el bien de este ejemplo
// Delegate to asynchronously invoke an action
private delegate void AsyncActionExecution();
Lets ASUME que el método Invoke es el punto de entrada que creará todos los hilos y esperará su ejecución. Así que tenemos:
public void Invoke()
{
_TotalThreads = N; /* Change with the total number of threads expected */
foreach (Object o in objects)
{
this.InvokeOneThread();
}
// Wait until execution has been completed
_CompletedHandle.WaitOne();
// Collect any exceptions thrown and bubble them up
foreach (WorkerThreadElement workerThreadElement in _WorkerThreadElements)
{
workerThreadElement.WorkerThread.EndInvoke(workerThreadElement.WorkerThreadResult);
}
}
InvokeOneThread es el método utilizado para crear un único hilo para una sola operación. Aquí tenemos que crear un elemento de hilo de trabajador e invocar el hilo real.
private void InvokeOneThread()
{
WorkerThreadElement threadElement = new WorkerThreadElement();
threadElement.WorkerThread = new AsyncActionExecution();
threadElement.WorkerThreadResult = threadElement.WorkerThread.BeginInvoke(actionParameters, InvokationCompleted, null);
_WorkerThreadElements.Add(threadElement);
}
de devolución de llamada de finalización hilo
private object _RowLocker = new object();
/// <summary>
/// Increment the number of rows that have been fully processed
/// </summary>
/// <param name="ar"></param>
private void InvokationCompleted(IAsyncResult ar)
{
lock (_RowLocker)
{
_RowsHandled++;
}
if (_TotalThreads == _ThreadsHandled)
_CompletedHandle.Set();
}
Hecho
El uso de datos dinámicos puede pasar su objeto y el WaitHandle (ActionResetEvent) que le permite esperar a que todos los subprocesos de fondo para terminar sin declarar una clase extra:
static void Main(string[] args)
{
List<AutoResetEvent> areList = new List<AutoResetEvent>();
foreach (MyObject o in ListOfMyObjects)
{
AutoResetEvent are = new AutoResetEvent(false);
areList.Add(are);
ThreadPool.QueueUserWorkItem(DoWork, new { o, are });
};
Console.WriteLine("Time: {0}", DateTime.Now);
WaitHandle.WaitAll(areList.ToArray());
Console.WriteLine("Time: {0}", DateTime.Now);
Console.ReadKey();
}
static void DoWork(object state)
{
dynamic o = state;
MyObject myObject = (MyObject)o.o;
AutoResetEvent are = (AutoResetEvent)o.are;
myObject.Execute();
are.Set();
}
- 1. Esperar a que finalicen los comandos
- 2. Esperando en PowerShell para que finalicen todos los procesos secundarios
- 3. C#: Esperando a que terminen todos los hilos
- 4. Esperar a que los hilos escriban cambios en el anzuelo
- 5. Enlazado de Bash: esperar a que terminen todos los hilos de trabajo no funciona?
- 6. ¿Espera a que terminen todos los hilos en un ejecutor?
- 7. ¿Cómo puedo esperar para que mis operaciones asincrónicas finalicen cuando se sale de la aplicación?
- 8. Esperando a que terminen todos los hilos en Spring Integration
- 9. Determinar cuándo terminaron todos los hilos C#
- 10. En Perl, ¿cómo puedo esperar a que los hilos terminen en paralelo?
- 11. sin detener todos los hilos en gdb
- 12. ¿Cómo esperar adecuadamente los procesos de primer plano/fondo en mi propio shell en C?
- 13. jQuery Ajax: ¿cómo esperar hasta que las solicitudes * async * finalicen antes de continuar?
- 14. hilos que activan C#
- 15. Volcar stacktraces de todos los hilos activos
- 16. ¿Interlocked proporciona visibilidad en todos los hilos?
- 17. QML: espere hasta que finalicen las animaciones
- 18. Cómo esperar a que un ThreadPoolExecutor termine
- 19. Cuantos recursos consumen los hilos para dormir y para esperar
- 20. Hacer que el comando "Esperar" de Linux espere a TODOS los procesos secundarios
- 21. Llamando a Hibernate en hilos de fondo en grises
- 22. ¿Cómo comienzo los hilos en C simple?
- 23. ¿Cómo notifica a un hilo principal que todos los hilos hijo han terminado?
- 24. Cómo liberar inmediatamente los hilos que esperan en un BlockingQueue
- 25. Cómo esperar a que un proceso finalice C++
- 26. hilos GEvent no terminan a pesar de que todos los elementos de la cola se agotan
- 27. ¿Cómo suspender todos los hilos después de que se cuelgue mi programa?
- 28. ¿Puedo obtener los rastros de la pila de todos los hilos en mi aplicación C#?
- 29. ¿Los hilos de fondo son una mala idea? ¿Por qué?
- 30. Señalización de todos los hilos en un proceso
posible duplicado de [C# freza varios subprocesos para trabajar y esperar hasta que todo termine] (http://stackoverflow.com/questions/2528907/c-spawn-multiple-threads-for-work-then-wait-until-all-finished) –
gracias por todas las respuestas rápidas a mi pregunta – RKP
has intentado [EventWaitHandle();] (http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx) – Bonshington