2012-07-17 34 views
8

Tôi muốn đợi hai nhiệm vụ để hoàn thành rồi trả về kết quả của chúng nhưng đôi khi tôi gặp phải lỗi này. Tại sao? CancellationException đã đến từ đâu?Hủy bỏ ngoại lệ khi sử dụng ExecutorService

public class ShouldVoteTask extends AbstractWorkerTask<Void, Void, Boolean> { 
    private final int placeID; 
    private final int userID; 

    public ShouldVoteTask(final int placeID, final int userID) { 
     this.placeID = placeID; 
     this.userID = userID; 
    } 

    @Override 
    protected Boolean doInBackground(final Void... params) { 
     try { 
      // Prepare callables. 
      final IsMaxRatingCallable call1 = new IsMaxRatingCallable(placeID); 
      final DidVoteCallable call2 = new DidVoteCallable(placeID, userID);   
      final List<Callable<Boolean>> callables = new ArrayList<Callable<Boolean>>();   
      callables.add(call1); 
      callables.add(call2); 

      // Execute them. 
      final ExecutorService service = Executors.newFixedThreadPool(2);    
      final List<Future<Boolean>> futures = service.invokeAll(callables, 5, TimeUnit.SECONDS); 

      // Check the result. 
      boolean result = true; 
      for(final Future<Boolean> future : futures) { 
       if(future.get()) { 
        result = false; 
       } 
      } 

      return result; 
     } catch (final InterruptedException e) { 
      e.printStackTrace(); 
     } catch (final ExecutionException e) { 
      e.printStackTrace(); 
     } 
     return false; 
    } 
} 

private class IsMaxRatingCallable implements Callable<Boolean> { 
    private final int placeID; 

    public IsMaxRatingCallable(final int placeID) { 
     this.placeID = placeID; 
    } 

    @Override 
    public Boolean call() throws Exception { 
     return Places.isMaxRating(placeID);   
    } 
} 

private class DidVoteCallable implements Callable<Boolean> { 
    private final int placeID; 
    private final int userID; 

    public DidVoteCallable(final int placeID, final int userID) { 
     this.placeID = placeID; 
     this.userID = userID; 
    } 

    @Override 
    public Boolean call() throws Exception { 
     return Votes.didVote(placeID, userID);   
    } 
} 

Lỗi

E/AndroidRuntime(19014): FATAL EXCEPTION: AsyncTask #1 
E/AndroidRuntime(19014): java.lang.RuntimeException: An error occured while executing doInBackground() 
E/AndroidRuntime(19014): at android.os.AsyncTask$3.done(AsyncTask.java:200) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
E/AndroidRuntime(19014): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
E/AndroidRuntime(19014): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
E/AndroidRuntime(19014): at java.lang.Thread.run(Thread.java:1027) 
E/AndroidRuntime(19014): Caused by: java.util.concurrent.CancellationException 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask.get(FutureTask.java:83) 
E/AndroidRuntime(19014): at com.vfa.android.planet.task.ShouldVoteTask.doInBackground(ShouldVoteTask.java:43) 
E/AndroidRuntime(19014): at com.vfa.android.planet.task.ShouldVoteTask.doInBackground(ShouldVoteTask.java:1) 
E/AndroidRuntime(19014): at android.os.AsyncTask$2.call(AsyncTask.java:185) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
E/AndroidRuntime(19014): ... 4 more 
+0

Những dòng là dòng 43? Và những gì trong dòng 1? Thật lạ khi dấu vết ngăn xếp của bạn hiển thị dòng 1. –

+0

43 >>> if (future.get()) {Có gì sai với nó? – Emerald214

+0

Tôi đoán rằng một trong các cuộc gọi của bạn đã ném một ngoại lệ. Bạn có thể đăng các mã cho những người? –

Trả lời

20

Bạn hỏi dịch vụ thi hành di chúc của bạn để thực hiện callables của bạn với một thời gian chờ 5 giây. Theo the javadoc:

nhiệm vụ chưa hoàn thành [vào cuối thời gian chờ] đang hủy

đoán của tôi là future.get() ném một CancellationException vì thời gian chờ đã đạt được và người thi hành gọi future.cancel() .

Bạn có thể một trong hai:

  • tăng thời gian chờ
  • bắt một InterruptedException trong callable bạn để xử lý việc hủy bỏ một cách duyên dáng
+0

Nhưng 'CancellationException' không mở rộng' InterruptedException' phải không? –

+0

BTW, tôi đang xử lý 'InterruptedException' xung quanh' invokeAll' và vẫn nhận được rằng 'CancellationException' –

+0

@ LuísSoares Không. – assylias

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