Funktioner för samtidighet i arbetsmiljön

Vi har sett att JFace UI-ramverket tillhandahåller grundläggande stöd för visning av aktivitetsförlopp i en dialogruta (se Tidskrävande åtgärder för mer information). I Infrastruktur för samtidighet, gick vi igenom plattformens körningsfunktioner för samtidiga och långvariga operationer. Nu ska vi ta en titt på hur plattformens användargränssnitt förbättrar denna infrastruktur i paketet org.eclipse.ui.progress. Detta paket tillhandahåller användargränssnittet för visning av jobbförlopp i arbetsmiljön och definierar ytterligare stöd för jobb som körs i UI-tråden.

Låt oss först ta en titt på de olika typerna av bakgrundsoperationer som kan vara igång och hur de visas i arbetsmiljöns användargränssnitt:


Givet en miljö där flera saker kan hända samtidigt, behöver en användare följande:

Förloppstjänst

Arbetsmiljöns förloppstjänst (IProgressService) är det primära gränssnittet till arbetsmiljöns förloppsstöd. Det kan erhållas från arbetsmiljön och sedan användas till att visa förloppet för både bakgrundsoperationer och operationer som körs i UI-tråden. Det främsta syftet med denna klass är att tillhandahålla en enda plats för körning av operationer och tar bort behovet för insticksprogramutvecklare att bestämma vilken mekanism som ska användas till att visa förlopp i en given situation. En annan fördel är att den förloppsdialogruta som visas med dessa metoder ger ett bra stöd att ange när en operation blockeras av en annan och ger användaren kontrollen att lösa konflikten. Där det är möjligt ska långvariga operationer köras med IProgressService#busyCursorWhile:

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

Den här metoden visar initialt en upptagenmarkör och ersätter den med en förloppsdialogruta om operationen varar längre än ett angivet tidsgränsvärde. Fördelen med denna metod jämfört med en förloppsdialogruta är att dialogrutan inte visas om operationen inte är långvarig. Om din operation måste uppdatera användargränssnittet kan du alltid använda Display.asyncExec eller Display.syncExec till att köra koden som modifierar användargränssnittet.

Om en operation måste köras i sin helhet i UI-tråden bör IProgressService#runInUI användas. Denna metod visar även en förloppsdialogruta om operationen blockeras och ger användaren kontroll.

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

Den tredje parametern kan vara null eller en schemaläggningsregel för operationen. I det här exemplet anger vi arbetsyteroten som egentligen låser arbetsytan medan denna UI-operation körs.

Du kan också registrera en ikon för en jobbfamilj med förloppstjänsten så att förloppsvyn kan visa ikonen bredvid jobbet som körs. Här är ett exempel som visar hur den automatiskt byggande jobbfamiljen associeras till sin ikon:

   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);

Visa att en del är upptagen

IWorkbenchSiteProgressService innehåller API för schemaläggning av jobb som ändrar utseendet på en arbetsmiljödel när jobbet körs. Om ditt insticksprogram kör bakgrundsoperationer som påverkar en dels läge, kan du schemalägga jobbet via delen och användaren får då återkoppling om att delen är upptagen. Här är ett exempel:

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

Förloppsegenskaper för jobb

Arbetsmiljön definierar förloppsrelaterade egenskaper för jobb i IProgressConstants . Dessa kan användas till att styra hur ett jobb visas i förloppsvyn. Dessa kan användas till att be förloppsvyn behålla (IProgressConstants#KEEP_PROPERTY) ditt jobb i vyn när det har slutförts eller att bara behålla ett (IProgressConstants#KEEPONE_PROPERTY) jobb åt gången i vyn. Du kan också associera en åtgärd (IProgressConstants#ACTION_PROPERTY) med ett jobb. När ett jobb har en associerad åtgärd visar förloppsvyn en hyperlänk så att en användare kan köra åtgärden. Du kan också få reda på om ett användarjobb visas i en förloppsdialogruta (IProgressConstants#PROPERTY_IN_DIALOG). Ett tips visas längst ned på statusraden när en åtgärd är tillgänglig. Följande exempel använder dessa egenskaper:

   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();

Arbetsmiljöjobb

Där det är möjligt ska långvariga operationer utföras utanför UI-tråden. Däremot kan detta inte alltid undvikas när operationens syfte är att uppdatera användargränssnittet. SWT-trådproblem beskriver hur detta kan göras med SWT-visning. Arbetsmiljön definierar ett specialjobb, UIJob, vars körningsmetod körs inuti en SWT asyncExec. Underklasser för UIJob ska implementera metoden runInUIThread istället för metoden run.

WorkbenchJob utökar UIJob så att jobbet bara kan schemaläggas eller köras när arbetsmiljön är igång. Som alltid ska du undvika omfattande arbete i UI-tråden eftersom användargränssnittet inte uppdateras under UI-jobbets varaktighet.