2010-07-30 11 views
13

W .net klasa AggregateException umożliwia zgłoszenie wyjątku zawierającego wiele wyjątków.Jaki jest równoważnik java wyrażenia AggregateException z .net?

Na przykład można rzucić wyjątek AggregateException, jeśli równolegle uruchomiono wiele zadań, a niektóre z nich nie powiodły się z wyjątkami.

Czy java ma równoważną klasę?

Szczególny przypadek chcę go używać w:

public static void runMultipleThenJoin(Runnable... jobs) { 
    final List<Exception> errors = new Vector<Exception>(); 
    try { 
     //create exception-handling thread jobs for each job 
     List<Thread> threads = new ArrayList<Thread>(); 
     for (final Runnable job : jobs) 
      threads.add(new Thread(new Runnable() {public void run() { 
       try { 
        job.run(); 
       } catch (Exception ex) { 
        errors.add(ex); 
       } 
      }})); 

     //start all 
     for (Thread t : threads) 
      t.start(); 

     //join all 
     for (Thread t : threads) 
      t.join();    
    } catch (InterruptedException ex) { 
     //no way to recover from this situation 
     throw new RuntimeException(ex); 
    } 

    if (errors.size() > 0) 
     throw new AggregateException(errors); 
} 
+0

nie jestem świadomy jednego. Jednak ja też nigdy nie szukałem. – Powerlord

Odpowiedz

3

Nie znam żadnych klas wbudowanych ani bibliotek, ponieważ nigdy wcześniej nie chciałem tego robić (zazwyczaj połączysz wyjątki), ale nie byłoby tak trudno napisz sam.

Można by prawdopodobnie chcesz wybrać jeden z wyjątków jest „podstawowy”, więc może być używany do wypełnienia stacktraces itp

public class AggregateException extends Exception { 

    private final Exception[] secondaryExceptions; 

    public AggregateException(String message, Exception primary, Exception... others) { 
     super(message, primary); 
     this.secondaryExceptions = others == null ? new Exception[0] : others; 
    } 

    public Throwable[] getAllExceptions() { 

     int start = 0; 
     int size = secondaryExceptions.length; 
     final Throwable primary = getCause(); 
     if (primary != null) { 
      start = 1; 
      size++; 
     } 

     Throwable[] all = new Exception[size]; 

     if (primary != null) { 
      all[0] = primary; 
     } 

     Arrays.fill(all, start, all.length, secondaryExceptions); 
     return all; 
    } 

} 
0

I naprawdę nie rozumiem, dlaczego należy użyć wyjątków w pierwszej kolejności, aby oznaczyć zadania jako niekompletny/powiodło, ale w każdym razie, że powinnam trudno je stworzyć samemu. Masz jakiś kod do udostępnienia, abyśmy mogli Ci pomóc w uzyskaniu bardziej szczegółowej odpowiedzi?

+0

Nie używam go do "zaznaczania" czegokolwiek, chcę tylko wskazać co najmniej jedną awarię. Zmieniłem główny post, aby dołączyć kod. –

+0

Jednym z przykładów jest to przydatne do sprawdzania poprawności. Zamiast rzucać wyjątek na pierwszą niepoprawną właściwość, sprawdź całą klasę, aby konsument mógł zrozumieć, dlaczego ładunek jest nieważny. To znacznie przyjemniejszy sposób na odkrycie interfejsu API. – Brandon

1

Można reprezentować wiele Taska jak

List<Callable<T>> tasks 

Następnie, jeśli chcesz komputer do faktycznie ich używania równoległego

ExecutorService executorService = .. initialize executor Service 
List<Future<T>> results = executorService.invokeAll () ; 

teraz można iteracyjne przez wyniki.

try 
{ 
    T val = result . get () ; 
} 
catch (InterruptedException cause) 
{ 
    // this is not the exception you are looking for 
} 
catch (ExecutionExeception cause) 
{ 
    Throwable realCause = cause . getCause () // this is the exception you are looking for 
} 

Tak realCause (jeśli istnieje) jest niezależnie od tego, co zostało zgłoszone w powiązanym z nim zadaniu.

+0

Miło jest widzieć, że istnieją już sposoby jednoczesnego uruchamiania zadań. Jednak Twoje rozwiązanie nie dotyczy zgłaszania wyjątku reprezentującego wiele niepowodzeń. –

Powiązane problemy