Understøttelse af arbejdsbænkssamtidighed

Vi har set, hvordan JFace UI-strukturen giver grundlæggende understøttelse til visning af opgavestatus i en dialogboks (der er flere oplysninger i Langvarige funktioner). I Samtidighedsinfrastruktur gennemgik vi platformens runtime-understøttelse af samtidighed og langvarige funktioner. Vi skal nu se på, hvordan platformsbrugergrænsefladen forbedrer infrastrukturen i pakken org.eclipse.ui.progress. Pakken leverer den brugergrænseflade, der viser jobstatus på arbejdsbænken, og definerer yderligere understøttelse af job, der udføres i brugergrænsefladeprogramdelen.

Lad os først se på de forskellige typer baggrundsfunktioner, der kan være i gang, og hvordan de vises på arbejdsbænkens brugergrænseflade:


I et miljø, hvor der kan ske flere ting på samme tid, har en bruger brug for følgende:

Statusservice

Arbejdsbænkens statusservice (IProgressService) er den primære grænseflade til arbejdsbænkens statusstøtte. Den kan hentes fra arbejdsbænken og derefter bruges til at vise status for baggrundsfunktioner og funktioner, som udføres i brugergrænsefladens programdel. Hovedformålet med klassen er at tilvejebringe et enkelt sted til udførelse af funktioner, som fjerner behovet for, at plugin-udviklere skal beslutte, hvilken mekanisme der skal bruges til at vise status i en given situation. En anden fordel er, at den statusdialogboks, som vises med disse metoder, giver god understøttelse til at angive, hvornår en funktion er blokeret af en anden, og giver brugeren mulighed for at løse konflikten. Hvor det er muligt, bør langvarige funktioner udføres med IProgressService#busyCursorWhile:

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

Metoden sætter som udgangspunkt en markør for optaget og erstatter den med en statusdialogboks, hvis funktionen tager længere tid end den angivne tidsgrænse. Fordelen med denne metode i modsætning til at bruge en statusdialogboks er, at statusdialogboksen ikke bliver vist, hvis funktionen er kortvarig. Du kan altid bruge Display.asyncExec eller Display.syncExec til at udføre den kode, der ændrer brugergrænsefladen, hvis din funktion skal opdatere brugergrænsefladen.

Hvis en funktion skal udføres i sin helhed i brugergrænsefladens programdel, skal du bruge IProgressService#runInUI. Denne metode viser også en statusdialogboks, hvis funktionen er blokeret og overgiver kontrollen til brugeren.

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

Den tredje parameter kan være NULL eller en planlægningsrute for funktionen. I dette eksempel angiver vi den rod for arbejdsområdet, der som udgangspunkt låser arbejdsområdet, men dens brugergrænsefladefunktion er i gang.

Du kan også registrere en ikon for en jobserie med statusservicen, så statusoversigten kan vise ikonen ved siden af det igangværende job. Det følgende er et eksempel på, hvordan jobserien til autobygning er knyttet til dens 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);

Vis, at en del er optaget

IWorkbenchSiteProgressService indeholder API til planlægning af job, der ændrer udseendet af en arbejdsbænksdel, mens jobbet er i gang. Hvis din plugin udfører baggrundsfunktioner, som påvirker tilstanden af en del, kan du planlægge jobbet via delen, og brugeren får tilbagemelding om, at delen er optaget. Her er et eksempel:

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

Statusegenskaber for job

Arbejdsbænken definerer statusrelaterede egenskaber for job i IProgressConstants. De kan bruges til at styre, hvordan et job vises i statusoversigten. De kan også bruges til at fortælle statusoversigten, at jobbet skal forblive i oversigten (IProgressConstants#KEEP_PROPERTY), når det er afsluttet, eller der kun skal være ét job i oversigten ad gangen (IProgressConstants#KEEPONE_PROPERTY). Du kan også knytte en funktion (IProgressConstants#ACTION_PROPERTY) til et job. Når et job har en tilknyttet funktion, viser statusoversigten et hyperlink, så brugeren kan udføre funktionen. Du kan også finde ud af, om der i øjeblikket vises et brugerjob i en statusdialogboks (IProgressConstants#PROPERTY_IN_DIALOG). Der vises et tip nederst til højre på statuslinjen, når en funktion er tilgængelig. Følgende eksempel bruger egenskaberne:

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

Arbejdsbænksjob

Hvor det er muligt, bør langvarige funktioner udføres uden for brugergrænsefladens programdel. Det kan imidlertid ikke altid undgås, hvis funktionen har til formål at opdatere brugergrænsefladen. Afsnittet Bemærkninger om programdele forklarer, hvordan det gøres ved hjælp af Display i SWT. Arbejdsbænken definerer et specialjob, UIJob, hvis run-metode udføres inde i en SWT asyncExec. Underklasser af UIJob skal implementere metoden runInUIThread i stedet for run-metoden.

WorkbenchJob udvider UIJob, så jobbet kun kan planlægges eller udføres, når arbejdsbænken er i gang. Du bør som altid undgå for meget arbejde i brugergrænsefladens programdel, fordi brugergrænsefladen ikke opfriskes, mens brugergrænsefladejobbet er i gang.