come fare in modo che il thread in primo piano attenda che tutti i thread in background (figlio) finiscano in C#? Devo ottenere l'elenco dei lavori in sospeso dalla coda (database), avviare un nuovo thread per eseguirli e infine attendere che tutti i thread figli finiscano. come farlo in C#? Grazie in anticipo.come aspettare che tutti i thread in background finiscano (in C#)?
risposta
Considerare l'utilizzo ThreadPool. La maggior parte di ciò che vuoi è già fatto. C'è un example from Microsoft che fa praticamente tutto il tuo compito. Sostituisci "fibonacci" con "compito del database" e suona come il tuo problema.
Ho letto questo articolo pochi minuti fa e stavo per rispondere dicendo che è la soluzione che stavo cercando. Grazie per la risposta. – RKP
È possibile memorizzare ogni thread avviato in una matrice. Quindi, quando è necessario attendere tutti, chiama il metodo Join su ciascun thread in una matrice in un ciclo.
Thread child = new Thread(...);
Threads.Add(child);
child.Start()
...
foreach(Thread t in Threads)
{
t.Join();
}
HTH
Grazie per la risposta. Penso che il metodo thread.Join è buono per un singolo thread o pochissimi il numero fisso di thread. per più thread, penso che ci sia un metodo WaitAll, ma non sono riuscito a trovare un buon esempio di codice per questo. – RKP
@RKP: aspettare che tutti i thread finiscano è come aspettare a loro volta, vero? C'è una funzione winapi WaitForMultipleObjects, ma non è C#, sebbene tu possa usarla, ma non vedo alcun punto. –
Questo è il codice incompleta, ma ManualResetEvent
lavori per voi
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());
Grazie, ma dove il nuovo thread per ogni azione viene avviato qui in questo codice? è "5000" un'impostazione di timeout? – RKP
Cerca qui l'intero codice, ho appena copiato un po 'da una delle mie risposte precedenti: http://stackoverflow.com/questions/3915017/image-url-validation-in-c/3915440#3915440 – danijels
E sì, 5000 è stato un timeout – danijels
Creare una struttura per tenere traccia dei tuoi thread di lavoro
private struct WorkerThreadElement
{
public IAsyncResult WorkerThreadResult;
public AsyncActionExecution WorkerThread;
}
È inoltre necessario tenere traccia del numero totale di thread che si prevede di creare e il numero di thread che hanno attualmente completato
private int _TotalThreads = 0;
private int _ThreadsHandled = 0;
private List<WorkerThreadElement> _WorkerThreadElements = new List<WorkerThreadElement>();
Quindi creare un handle autoreset per attendere il completamento del thread.
// The wait handle thread construct to signal the completion of this process
private EventWaitHandle _CompletedHandle = new AutoResetEvent(false);
È inoltre necessario un delegato per creare nuove discussioni - Ci sono diversi modi di fare questo, ma ho scelto un semplice delegato per il bene di questo esempio
// Delegate to asynchronously invoke an action
private delegate void AsyncActionExecution();
Consente asume che il metodo Invoke è il punto di ingresso che creerà tutti i thread e attenderà la loro esecuzione. Quindi:
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 è il metodo utilizzato per creare un singolo thread per un'operazione. Qui abbiamo bisogno di creare un elemento thread di lavoro e richiamare il thread attuale.
private void InvokeOneThread()
{
WorkerThreadElement threadElement = new WorkerThreadElement();
threadElement.WorkerThread = new AsyncActionExecution();
threadElement.WorkerThreadResult = threadElement.WorkerThread.BeginInvoke(actionParameters, InvokationCompleted, null);
_WorkerThreadElements.Add(threadElement);
}
richiamata dal completamento filo
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();
}
Fatto
Utilizzando i dati dinamici è possibile passare l'oggetto e il WaitHandle (ActionResetEvent) che consente di attendere per tutti i thread in background per terminare senza dichiarare una classe in più:
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. Attendi che finiscano tutti i thread in un Executor?
- 2. La mia classe AsyncTask contiene altri thread. Come posso aspettare che finiscano tutti i suoi thread prima di eseguire un metodo seguente?
- 3. C# che sospende tutti i thread
- 4. non interrompe tutti i thread in gdb
- 5. In Perl, come posso aspettare che i thread terminino in parallelo?
- 6. Attendi che i metodi asincroni finiscano in un ciclo for
- 7. Attendi che tutti i processi di multiprocesso finiscano prima di continuare
- 8. Come uccidere tutti i processi in background in zsh?
- 9. Elenca tutti i thread
- 10. Chiamata Hibernate in background thread in grails
- 11. In che modo Dispatcher differisce dal thread in background?
- 12. Come posso fare in modo che Perl aspetti i processi figli avviati in background con system()?
- 13. Come aspettare che un'animazione finisca in viewDidDisappear?
- 14. Interblocco fornisce visibilità in tutti i thread?
- 15. Notifica avanzamento thread in background in MVVM?
- 16. In g ++ è il modello di thread C++ 11 che utilizza pthreads in background?
- 17. In che modo Android gestisce i thread in background quando si lascia un'attività?
- 18. Django: avvia un processo in un thread in background?
- 19. WPF Dispatcher.BeginInvoke e UI/thread in background
- 20. Come forzare Task.Factory.StartNew in un thread in background?
- 21. Webdriver Come aspettare che l'elemento sia cliccabile nel webdriver C#
- 22. Salvataggio in background con i dati principali?
- 23. Come aspettare che una transizione termini in javafx 2.1?
- 24. Elenca tutti i thread in esecuzione/in coda in ThreadPoolTaskExecutor
- 25. Come utilizzare LoadKeyboardLayout in un thread in background?
- 26. Decodifica le immagini nel thread in background?
- 27. JavaFX - Thread in background per query SQL
- 28. glGenTextures restituisce zero nella thread in background
- 29. La best practice su come aspettare i dati all'interno del thread e scriverli in un file?
- 30. PyCharm - come sospendere tutti i thread
possibile duplicato del [C# Spawn Fili multipli per lavora quindi aspetta fino a quando tutto è finito] (http://stackoverflow.com/questions/2528907/c-spawn-multiple-threads-for-work-then-wait-until-all-finished) –
grazie per tutte le risposte rapide a la mia domanda – RKP
hai provato [EventWaitHandle();] (http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx) – Bonshington