Workbench 동시성 지원

JFace UI 프레임워크가 대화 상자에 타스크 진행을 표시하기 위한 기본 지원을 제공하는 것을 살펴보았습니다(자세한 내용은 장기 실행 조작 참조). 동시성 하부구조에서 동시성 및 장기 실행 조작에 대한 플랫폼 런타임 지원을 검토했습니다. 이제 플랫폼 UI가 org.eclipse.ui.progress 패키지에서 이 하부구조를 향상시키는 방법에 대해 살펴봅니다. 이 패키지는 Workbench에 작업 진행을 표시하는 UI를 제공하고 UI 스레드에서 실행하는 작업에 대한 추가 지원을 정의합니다.

첫 번째, 실행 중일 수 있는 여러 가지 종류의 배경 조작 및 이들이 Workbench UI에 표시되는 방법을 찾으십시오.


여러 가지 사항이 동시에 발생할 수 있는 환경을 고려하면 사용자는 다음이 필요합니다.

진행 서비스

Workbench 진행 서비스(IProgressService)는 Workbench 진행 지원에 대한 기본 인터페이스입니다. 이는 Workbench에서 확보하여 배경 조작과 UI 스레드에서 실행하는 조작에 대해 진행 보기를 표시하는 데 사용될 수 있습니다. 이 클래스의 기본 목적은 실행 중인 조작에 대한 원스톱 쇼핑(one-stop shopping)을 제공하여 플러그인 개발자가 해당 상황에서 진행을 표시하는 데 사용할 메커니즘을 결정할 필요가 없도록 하는 것입니다. 다른 장점은 이 메소드로 표시된 진행 대화 상자가 다른 사용자에 의해 조작이 차단되는 경우를 표시하기 위한 지원을 제공하고 충돌을 해결하는 사용자 제어를 제공하는 것입니다. 가능한 경우 IProgressService#busyCursorWhile을 사용하여 장기 실행 조작이 실행되어야 합니다.

   IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
   progressService.busyCursorWhile(new IRunnableWithProgress(){
         public void run(IProgressMonitor monitor) {
         //do non-UI work
      }
   });

조작이 지정된 시간 임계값보다 오래 지속되는 경우 이 메소드가 사용 중인 커서를 진행 대화 상자로 대체합니다. 진행 대화 상자 사용에 대한 이 메소드의 장점은 조작이 짧게 실행되는 경우 진행 대화 상자가 표시되지 않는다는 점입니다. 조작이 UI를 갱신해야 하는 경우 항상 Display.asyncExec 또는 Display.syncExec를 사용하여 UI를 수정하는 코드를 실행할 수 있습니다.

조작이 UI 스레드에서 완전히 실행되어야 하는 경우 IProgressService#runInUI가 사용되어야 합니다. 이 메소드는 또한 조작이 블록되는 경우 진행 대화 상자를 표시하고 사용자 제어를 제공합니다.

   progressService.runInUI(
      PlatformUI.getWorkbench().getProgressService(),
      new IRunnableWithProgress() {
         public void run(IProgressMonitor monitor) {
            //do UI work
         }
      },
      Platform.getWorkspace().getRoot());

세 번째 매개변수는 널(null)이거나 조작의 스케줄링 규칙일 수 있습니다. 이 예제에서는 이 UI 조작이 실행하는 동안 작업공간을 잠그는 작업공간 루트를 지정합니다.

또한 진행 보기가 실행 중인 작업 옆에 아이콘을 표시할 수 있도록 진행 서비스에 작업 제품군에 대한 아이콘을 등록할 수 있습니다. 다음은 자동 빌드 작업 제품군이 해당 아이콘과 연관되는 방법을 표시하는 예제입니다.

   IProgressService service = PlatformUI.getWorkbench().getProgressService();
   ImageDescriptor newImage = IDEInternalWorkbenchImages.getImageDescriptor(
      IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC);
   service.registerIconForFamily(newImage, ResourcesPlugin.FAMILY_MANUAL_BUILD);
   service.registerIconForFamily(newImage, ResourcesPlugin.FAMILY_AUTO_BUILD);

부분이 사용 중임을 표시

IWorkbenchSiteProgressService는 작업이 실행되는 동안 Workbench 부분의 모양을 변경하는 작업 스케줄용 API를 포함하고 있습니다. 플러그인이 부분의 상태에 영향을 주는 배경 조작을 실행 중인 경우 부분을 통해 작업을 스케줄할 수 있으며 사용자는 부분이 사용 중이라는 피드백을 받게 됩니다. 예를 들면 다음과 같습니다.

   IWorkbenchSiteProgressService siteService =
      (IWorkbenchSiteProgressService)view.getSite().getAdapter(IWorkbenchSiteProgressService.class);
   siteService.schedule(job, 0 /* now */, true /* use the half-busy cursor in the part */);

작업의 진행 특성

Workbench가 IProgressConstants에 작업에 대한 진행 관련 특성을 정의합니다. 이들은 작업이 진행 보기에 표시되는 방법을 제어하는 데 사용할 수 있습니다. 이것은 진행 보기가 완료된 후 보기에 (IProgressConstants#KEEP_PROPERTY) 작업을 유지하거나 한번에 하나의 (IProgressConstants#KEEPONE_PROPERTY) 작업을 보기에 유지하도록 지시하는 데 사용할 수 있습니다. 조치를 (IProgressConstants#ACTION_PROPERTY) 작업과 연관시킬 수도 있습니다. 작업에 연관된 조치가 있으면 사용자가 조치를 실행할 수 있도록 진행 보기는 하이퍼링크를 표시합니다. 사용자 작업이 진행 대화 상자에 표시되는지 찾아낼 수도 있습니다(IProgressConstants#PROPERTY_IN_DIALOG). 조치가 사용 가능한 시기에 대한 힌트가 상태 표시줄 오른쪽 맨아래에 제공됩니다. 다음 예제는 이들 특성을 사용합니다.

   Job job = new Job("Do Work") {
         public IStatus run(IProgressMonitor monitor) {
         // do some work.  
         // Keep the finished job in the progress view only if it is not running in the progress dialog
         Boolean inDialog = (Boolean)getProperty(IProgressConstants.PROPERTY_IN_DIALOG);
         if(!inDialog.booleanValue())
            setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE);
      }
   };
   job.setProperty(IProgressConstants.ICON_PROPERTY, Plugin.getImageDescriptor(WORK_IMAGE));
   IAction gotoAction = new Action("Results") {
public void run() {
         // show the results
      }
   };
   job.setProperty(IProgressConstants.ACTION_PROPERTY, gotoAction);
   job.setUser(true);
   job.schedule();

Workbench 작업

가능한 경우 UI 스레드 외부에서 장기 실행 오퍼레이션을 수행해야 합니다. 그러나 오퍼레이션의 목적이 UI를 갱신하는 것일 경우 UI 스레드에서 수행되어야 합니다. SWT 스레딩 문제에서는 SWT Display를 사용하여 완료할 수 있는 방법에 대해 설명합니다. Workbench에서는 실행 메소드가 SWT asyncExec에서 실행되는 특수 작업 UIJob에 대해 정의합니다. UIJob의 서브클래스는 run 메소드 대신 runInUIThread 메소드를 구현해야 합니다.

WorkbenchJob은 Workbench가 실행될 때만 작업을 스케줄하거나 실행하도록 UIJob을 확장합니다. UI 작업의 지속기간 동안 UI가 새로 고쳐지지 않으므로 항상 UI 스레드에서 과도한 작업을 피해야 합니다.