2017-11-26 40 views
2

vaadin 프레임 워크 내에서 push를 사용하여 화면을 업데이트하는 코드를 호출하려고합니다. 그러나 프로세스가 너무 오래 걸릴 수 있기를 원합니다. 그것을 취소하십시오.SimpleTimeLimiter (Guava)를 Vaadin과 함께 사용하는 방법

내가 구아바의 SimpleTimeLimiter 클래스를 사용하려고했지만, 내가 무엇을 하든지간에 Vaadin 프로세스가 멈추는 것을 막을 수는 없다. 나는 SimpleTimeLimiterUI.getCurrent().access() 메서드 안에 넣고 그 둘 모두를 시도했지만, SimpleTimeLimiterTimeoutException 인 경우에도 프로세스를 계속 실행합니다. 나는 정상적인 스레드와 동일한 코드를 사용하는 경우이 방법은 1 초 이상 걸리는 경우가 TimeoutException을 던져 알림 창을 넣어 것입니다 위의 코드에서 ...

public static void limitExecutionTime(Consumer<UI> lambda) 
{ 
    UI currentUI = UI.getCurrent(); 

    UI.getCurrent().access(() -> 
    { 
     try 
     { 
      SimpleTimeLimiter.create(Executors.newSingleThreadExecutor()).callWithTimeout(new Callable<Void>() 
      { 
       @Override 
       public Void call() 
       { 
        // This is needed to deal how Vaadin 8 handles UI's 
        UI.setCurrent(currentUI); 
        lambda.accept(); 
        return null; 
       } 
      }, 1, TimeUnit.SECONDS); 

     } catch (TimeoutException | InterruptedException | ExecutionException e) { 
      NotificationUtils.showError("Execution took beyond the maximum allowed time."); 
      currentUI.push(); 
     } 
    }); 
} 

을 작동하는 것 같다. 그러나 그것은 람다를 계속 실행합니다. 내가 반대를하려고 노력하고 public Void call() 방법에 UI.getCurrent().access()을 넣어하지만이 동일한 결과를 했어 결과

...

당신은 당신의 백그라운드 작업 후 UI.access를 호출해야

답변

3

로 업데이트 할 준비가 일부 데이터. access 메서드를 사용하면 사용자가보고있는 페이지에서 변경 작업을 수행 할 수 있습니다.

당신의 예에서

배경 작업 실행, 당신은 call 방법에 작업 취소 메시지를 전달하는 방법을 누락되었습니다. 외부 이벤트 (예 : 취소 버튼 클릭)에서 작업 취소를 준비하려면이 작업을 내부에서 고려해야합니다. 다음 예는 Future.cancel을 사용하여 취소 방법을 제공하는 방법을 보여줍니다.

작업을 시작할 때이 방법은 다음과

private void simulateLongAndSlowCalculation() { 
    while (moreWorkTodo) { 
     if (Thread.currentThread().isInterrupted()) { 
      return; 
     } 
     try { 
      doSomeBlockingCallThatCanBeInterrupted(); 
     } catch (InterruptedException e) { 
      Thread.currentThread().interrupt(); 
      return; 
     } 
    } 
} 

시작 작업 및 UI.access에서 처리 할 수있는 실제 작업 내부

private void onCancelClick(Button.ClickEvent clickEvent) { 
    // This method is called from Vaadin UI thread. We will signal 
    // background task thread to stop. 
    futureResult.cancel(true); 
} 

다음보기는 작업을 생성하고에 제출해야한다 집행자 서비스.

private void onButtonClick(Button.ClickEvent clickEvent) { 
    // This runTask creates important link to current UI and the background task. 
    // "this" object in these onTask methods is the UI object that we want 
    // to update. We need to have someway to pass UI object to background 
    // thread. UI.getCurrent() could be a parameter that is passed to the 
    // task as well. 
    Future<String> futureResult = taskService.runTask(
      this::onTaskDone, 
      this::onTaskCancel, 
      this::onTaskProgress); 
    progressDialog = new ProgressDialog(futureResult); 
    progressDialog.show(); 
} 

이제 UI를 업데이트하려면 UI.access 메서드가 필요합니다. 이 예에서, 그것은 다음과 같은 경우에 발생할 수

  1. 작업은
  2. 작업 진행
  3. 작업은 다음과 같은 방법 this 모두가 참조하는

참고 취소있어 업데이트 된 성공적으로 완료 작업을 시작한 UI 객체입니다. 그래서 우리는 올바른 UI를 result로 업데이트하고 다른 사용자의 UI는 업데이트하지 않습니다.

코드에서 UI.setCurrent를 호출 할 필요가 없습니다.

https://github.com/m1kah/vaadin-background-task

편집 : 배경 작업에 대한 추가 섹션

private void onTaskProgress(double progress) { logger.info("onTaskProgress: {}", progress); access(() -> progressDialog.setProgress(progress)); } private void onTaskCancel() { logger.info("onTaskCancel"); access(() -> { progressDialog.close(); setResult("Cancelled"); }); } private void onTaskDone(String result) { logger.info("onTaskDone"); access(() -> { progressDialog.close(); setResult(result); }); } 

예 프로젝트

내가 취소 버튼에서 백그라운드 작업을 취소하는 방법을 보여줍니다 GitHub의 또 다른 프로젝트를 밀어 및 UI.access. 예제 프로젝트 링크가 다른 예제로 업데이트되었습니다.

+0

나는 그것을 시도했지만 작동하지 않았다. 기본적으로 x 시간이 지나면 UI.access 작업을 죽일 수있는 방법을 찾을 수 없습니다. 즉, 공용 Void 호출 메서드에서 UI.getCurrent(). access()를 실행하여 표시되는 방식 대신 실행했습니다. 같은 결과 였지만 TimeoutException이 있더라도 access()가 계속되었습니다. –

+0

@StephaneGrenier 주제에 대해 더 많은 것을 가지고 나의 답변을 업데이트 + 더 나은 예제 프로젝트를 만들었습니다 :) – Mika

+0

자세한 예제와 샘플 코드를 보내 주셔서 감사합니다. 정말 고맙습니다. 제 관심사는 코드와 구아바의 SimpleTimeLimiter의 차이점은 무엇입니까? 바퀴의 많은 발명품이 있습니까? 내가 코드를 정확히 이해한다면 기본적으로 인터럽트 시간이 있는지 폴링하고있는 것입니까? –