Warten Sie, bis Future <T> abgeschlossen ist

Es werden nur wenige asynchrone Aufgaben ausgeführt und ich muss warten, bis mindestens eine abgeschlossen ist (in Zukunft muss ich wahrscheinlich warten, bis M von N Aufgaben abgeschlossen sind). Derzeit werden sie als Zukunft dargestellt, also brauche ich sowas

/**
 * Blocks current thread until one of specified futures is done and returns it. 
 */
public static <T> Future<T> waitForAny(Collection<Future<T>> futures) 
        throws AllFuturesFailedException

Gibt es so etwas? Oder etwas Ähnliches, nicht notwendig für die Zukunft. Momentan durchlaufe ich die Futures-Sammlung, überprüfe, ob eine abgeschlossen ist, schlafe einige Zeit und überprüfe sie erneut. Dies scheint nicht die beste Lösung zu sein. Wenn ich über einen längeren Zeitraum schlafe, kommt eine unerwünschte Verzögerung hinzu. Wenn ich über einen kurzen Zeitraum schlafe, kann dies die Leistung beeinträchtigen.

Ich könnte es versuchen

new CountDownLatch(1)

und verringern Sie den Countdown, wenn die Aufgabe abgeschlossen ist

countdown.await()

, aber ich fand es nur möglich, wenn ich die zukünftige Schöpfung kontrolliere. Dies ist möglich, erfordert jedoch eine Umgestaltung des Systems, da derzeit die Logik der Aufgabenerstellung (Senden von Callable an ExecutorService) von der Entscheidung, auf welche Zukunft zu warten, getrennt ist. Ich könnte es auch überschreiben

<T> RunnableFuture<T> AbstractExecutorService.newTaskFor(Callable<T> callable)

und erstellen Sie eine benutzerdefinierte Implementierung von RunnableFuture mit der Möglichkeit, einen Listener anzuhängen, der benachrichtigt wird, wenn die Aufgabe abgeschlossen ist. Anschließend können Sie diesen Listener an die erforderlichen Aufgaben anhängen und CountDownLatch verwenden. Dies bedeutet jedoch, dass ich newTaskFor für jeden von mir verwendeten ExecutorService überschreiben muss die AbstractExecutorService nicht erweitern. Ich könnte auch versuchen, einen gegebenen ExecutorService für den gleichen Zweck zu verpacken, aber dann muss ich alle Methoden, die Futures erzeugen, dekorieren.

All diese Lösungen mögen funktionieren, wirken aber sehr unnatürlich. Es sieht so aus, als würde mir etwas Einfaches fehlen

WaitHandle.WaitAny(WaitHandle[] waitHandles)

in c #. Gibt es bekannte Lösungen für solche Probleme?

AKTUALISIEREN:

Ursprünglich hatte ich überhaupt keinen Zugang zu Future Creation, daher gab es keine elegante Lösung. Nach der Neugestaltung des Systems bekam ich Zugriff auf Future Creation und konnte countDownLatch.countdown () zum Ausführungsprozess hinzufügen, dann kann ich countDownLatch.await () und alles funktioniert gut. Vielen Dank für andere Antworten, ich wusste nichts über ExecutorCompletionService und es kann in der Tat bei ähnlichen Aufgaben hilfreich sein, aber in diesem speziellen Fall konnte es nicht verwendet werden, da einige Futures ohne Executor erstellt werden - die eigentliche Aufgabe wird über das Netzwerk an einen anderen Server gesendet. wird aus der Ferne ausgeführt und es wird eine Abschlussbenachrichtigung empfangen.

Antworten auf die Frage(7)

Ihre Antwort auf die Frage