2010-07-30 34 views
13

Trong .net lớp AggregateException cho phép bạn ném một ngoại lệ có chứa nhiều ngoại lệ.Tương đương java của AggregateException từ .net là gì?

Ví dụ: bạn sẽ muốn ném một ngoại lệ AggregateException nếu bạn chạy nhiều tác vụ song song và một số trong số chúng không thành công với ngoại lệ.

Java có lớp tương đương không?

Các trường hợp cụ thể tôi muốn sử dụng nó trong:

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

Tôi không biết của ai. Tuy nhiên, tôi chưa bao giờ tìm kiếm một. – Powerlord

Trả lời

3

Tôi không biết về bất kỳ lớp học tích hợp hoặc thư viện nào, vì tôi chưa bao giờ muốn làm điều này trước đây (thông thường bạn chỉ cần chuỗi các trường hợp ngoại lệ), nhưng sẽ không khó tự viết.

Bạn có thể muốn chọn một trong các trường hợp ngoại lệ là "chính" để nó có thể được sử dụng để điền vào stacktraces vv

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

tôi không thực sự hiểu tại sao bạn nên sử dụng ngoại lệ ở nơi đầu tiên để đánh dấu nhiệm vụ không đầy đủ/thất bại nhưng trong mọi trường hợp, nó shouldn không khó để tạo ra một mình. Có bất kỳ mã nào để chia sẻ để chúng tôi có thể giúp bạn với câu trả lời cụ thể hơn không?

+0

Tôi không sử dụng nó để 'đánh dấu' bất cứ điều gì, tôi chỉ muốn chỉ ra ít nhất một lỗi. Tôi đã chỉnh sửa bài đăng chính để bao gồm mã. –

+0

Một ví dụ này hữu ích là để xác thực. Thay vì ném ngoại lệ vào thuộc tính không hợp lệ đầu tiên, hãy xác thực toàn bộ lớp để người tiêu dùng có thể hiểu tại sao tải trọng không hợp lệ. Đây là một cách tốt hơn để khám phá một API. – Brandon

1

Bạn có thể đại diện cho nhiều taska như

List<Callable<T>> tasks 

Sau đó, nếu bạn muốn máy tính để thực sự làm cho họ được sử dụng song song

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

Bây giờ bạn có thể lặp thông qua kết quả.

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 
} 

Vì vậy, nguyên nhân thực sự (nếu có) là ngoại lệ.

+0

Thật tuyệt khi thấy rằng đã có nhiều cách để chạy nhiệm vụ đồng thời. Tuy nhiên, giải pháp của bạn không giải quyết việc ném một ngoại lệ biểu diễn nhiều thất bại nhiệm vụ. –

Các vấn đề liên quan