wie der Vordergrund-Thread auf alle Hintergrund (untergeordneten) Threads warten in C# zu beenden? Ich muss eine Liste der ausstehenden Jobs aus der Warteschlange (Datenbank) abrufen, einen neuen Thread starten, um sie auszuführen, und schließlich auf alle untergeordneten Threads warten. wie geht das in C#? Danke im Voraus.Wie warten Sie, bis alle Hintergrundthreads fertig sind (in C#)?
Antwort
Betrachten Threadpool verwenden. Das meiste von dem, was Sie wollen, ist bereits erledigt. Es gibt eine example from Microsoft, die so ziemlich deine gesamte Aufgabe erledigt. Ersetzen Sie "fibonacci" durch "database task" und es klingt wie Ihr Problem.
Ich las diesen Artikel ein paar Minuten zurück und war im Begriff zu sagen, das ist die Lösung, die ich suchte. danke für die Antwort. – RKP
Sie könnten jeden gestarteten Thread in einem Array speichern. Wenn Sie dann auf alle warten müssen, rufen Sie die Join-Methode für jeden Thread in einem Array in einer Schleife auf.
Thread child = new Thread(...);
Threads.Add(child);
child.Start()
...
foreach(Thread t in Threads)
{
t.Join();
}
HTH
Danke für die Antwort. Ich denke thread.Join Methode ist gut für einen einzelnen Thread oder sehr wenige feste Anzahl von Threads. Für mehrere Threads denke ich, dass es eine WaitAll-Methode gibt, aber ich konnte kein gutes Codebeispiel dafür finden. – RKP
@RKP: Warten auf alle Threads zu beenden ist das gleiche wie auf sie zu warten, nicht wahr? Es gibt eine winapi-Funktion WaitForMultipleObjects, aber es ist nicht C#, obwohl Sie es verwenden können, aber ich sehe keinen Sinn. –
Dies ist unvollständig Code, aber ManualResetEvent
Arbeiten für Sie
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());
Danke, aber wo wird der neue Thread für jede Aktion hier in diesem Code gestartet? ist "5000" eine Zeitüberschreitung? – RKP
Schauen Sie hier für den gesamten Code, ich habe nur ein bisschen von einer meiner früheren Antworten kopiert: http://StackOverflow.com/Questions/3915017/image-URL-validation-in-C/3915440#3915440 – danijels
Und ja, 5000 war eine Timeout-Einstellung – danijels
eine Struktur erstellen Überblick über Ihre Arbeitsthreads zu halten
private struct WorkerThreadElement
{
public IAsyncResult WorkerThreadResult;
public AsyncActionExecution WorkerThread;
}
Sie müssen auch Verfolgen Sie die Gesamtzahl der zu erstellenden Threads und die Anzahl der aktuell vorhandenen Threads abgeschlossen
private int _TotalThreads = 0;
private int _ThreadsHandled = 0;
private List<WorkerThreadElement> _WorkerThreadElements = new List<WorkerThreadElement>();
Erstellen Sie dann ein Autoreset-Handle, um auf die Beendigung des Threads zu warten.
// The wait handle thread construct to signal the completion of this process
private EventWaitHandle _CompletedHandle = new AutoResetEvent(false);
Sie auch einen Delegaten brauchen neue Themen zu erstellen - Es gibt mehrere Möglichkeiten, dies zu tun, aber ich habe einen einfachen Delegierten zum Zwecke dieses Beispiels
// Delegate to asynchronously invoke an action
private delegate void AsyncActionExecution();
Lets asume dass die Invoke-Methode gewählt ist der Eingangspunkt, der alle Threads erstellt und auf deren Ausführung wartet. So haben wir:
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 ist die Methode, um einen einzelnen Thread für eine Operation zu erstellen. Hier müssen wir ein Worker-Thread-Element erstellen und den aktuellen Thread aufrufen.
private void InvokeOneThread()
{
WorkerThreadElement threadElement = new WorkerThreadElement();
threadElement.WorkerThread = new AsyncActionExecution();
threadElement.WorkerThreadResult = threadElement.WorkerThread.BeginInvoke(actionParameters, InvokationCompleted, null);
_WorkerThreadElements.Add(threadElement);
}
Rückruf von Gewinden Abschluss
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();
}
Fertig
Verwendung dynamischer Daten, die Sie Ihr Objekt und das Waithandle (ActionResetEvent) passieren kann, dass Sie für alle Hintergrund-Threads ohne erklärt eine zusätzliche Klasse zu beenden warten lässt:
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. Warten Sie, bis alle Arbeiter fertig sind
- 2. Warten Sie, bis alle Threads im Service fertig sind.
- 3. UI hängt, bis alle Abrufe fertig sind
- 4. Warten, bis System.Diagnostics.Process.Start fertig ist
- 5. Wie warten, bis ein ThreadPoolExecutor fertig ist
- 6. Erstellen Sie mehrere Threads und warten Sie, bis alle fertig sind
- 7. Warten bis Tomcat fertig ist
- 8. Wie warten, bis ein Animator fertig ist?
- 9. Warten, bis alle Subprozesse abgeschlossen sind?
- 10. Laden Sie mehrere Dateien asynchron herunter und warten Sie, bis alle fertig sind, bevor Sie den Rest des Codes ausführen.
- 11. Warten bis ein SwingWorker fertig ist?
- 12. Java warten, bis JFrame fertig ist
- 13. Warten, bis gepoolte Threads abgeschlossen sind
- 14. Pause Scrollen zum nächsten "Slide" bis alle Animationen fertig sind
- 15. Warten Sie, bis der Ajax-Anruf für Capybara fertig ist.
- 16. Wie warten, bis mehrere Threads abgeschlossen sind?
- 17. Meteor: warten, bis alle Vorlagen
- 18. jquery: warten, bis alle Ajax-Aufrufe dann
- 19. Ausführen von CKQuery in AppDelegate - warten bis fertig
- 20. Warten bis mehrere Befehlszeilenprozesse abgeschlossen sind?
- 21. NodeJS warten bis alle Async-Befehle abgeschlossen sind
- 22. Warten, bis mehrere AsyncTask abgeschlossen sind
- 23. jQuery UI-Dialog - warten bis die Animation fertig ist
- 24. QML: warte bis Animationen fertig
- 25. Warten, bis die Threads fertig sind, bevor der nächste Schritt ausgeführt wird
- 26. Warten, bis pthread_create fertig ist, ohne pthread_join zu verwenden
- 27. VBScript scheint zu warten, bis Excel Macro fertig ist?
- 28. Mehrere Werte parallel berechnen. Warten Sie, bis alle Threads beendet sind.
- 29. So warten Sie, bis alle Bulk-Schreibvorgänge in der elastischen Such-API abgeschlossen sind
- 30. Warten Sie, bis Versprechen und verschachtelte thens abgeschlossen sind
möglich Duplikat [C# Spawn mehrere Threads für arbeite dann warte bis alles fertig ist] (http://stackoverflow.com/questions/2528907/c-spawn-multiple-threads-for-work-then-wait-until-all-finished) –
danke für alle schnellen Antworten auf Meine Frage – RKP
haben Sie versuchen [EventWaitHandle();] (http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.aspx) – Bonshington