Støtte for samtidighet i arbeidsbenken

Vi har sett at rammeverket for JFace-brukergrensesnittet gir grunnleggende støtte for visning av oppgavefremdrift i en dialogboks (du finner mer informasjon under Tidkrevende operasjoner). Under Infrastruktur for samtidighet så vi på plattformens kjøretidsstøtte for samtidighet og tidkrevende operasjoner. Vi skal nå se nærmere på hvordan plattformens brukergrensesnitt forbedrer denne infrastrukturen i pakken org.eclipse.ui.progress. Denne pakken inneholder brukergrensesnittet for visning av jobbfremdrift i arbeidsbenken og definerer ytterligere støtte for jobber som kjører i brukergrensesnittråden.

La oss først se på de ulike bakgrunnsoperasjonene som kjører og hvordan de vises i arbeidsbenkens brukergrensesnitt:


En bruker trenger følgende i et miljø der det skjer flere ting samtidig:

Fremdriftstjeneste

Arbeidsbenkens fremdriftstjeneste (IProgressService) er det primære grensesnittet for arbeidsbenkens fremdriftsstøtte. Dette kan hentes fra arbeidsbenken og deretter brukes for å vise fremdrift både for bakgrunnsoperasjoner og operasjoner som kjøres i brukergrensesnittråden. Hovedformålet med denne klassen er å oppgi ett sted for kjøring av operasjoner, noe som fjerner behovet for at plugin-utviklere må avgjøre hva slags mekanisme som skal brukes for å vise fremdriften i en gitt situasjon. En annen fordel er at fremdriftsdialogboksen som vises med disse metodene, gir god støtte for å angi når en operasjon blokkeres av en annen operasjon og gir brukeren kontroll til å løse konflikten. Der det er mulig skal tidkrevende operasjoner kjøres ved hjelp av IProgressService#busyCursorWhile:

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

Denne metoden viser først en opptattmarkør som erstattes med en fremdriftsdialogboks, hvis operasjonen varer lenger enn en oppgitt tidsgrenseverdi. Fordelen med denne metoden fremfor en fremdriftsdialogboks, er at fremdriftsdialogboksen ikke blir vist hvis ikke operasjonen er langvarig. Hvis operasjonen skal oppdatere brukergrensesnittet, kan du alltid bruke Display.asyncExec eller Display.syncExec for å kjøre koden som endrer brukergrensesnittet.

Hvis en operasjon i sin helhet skal kjøres i brukergrensesnittråden, må IProgressService#runInUI brukes. Denne metoden viser også en fremdriftsdialogboks hvis operasjonen er blokkert og gir brukeren kontroll.

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

Den tredje parameteren kan være null eller en planleggingsregel for operasjonen. I dette eksempelet angir vi arbeidsområderoten som låser arbeidsområdet mens brukergrensesnittoperasjonen kjøres.

Du kan også registrere et jobbfamilieikon med fremdriftstjenesten slik at fremdriftsvisningen viser ikonet ved siden av jobben som kjøres. Her er et eksempel som viser hvordan den automatisk bygde jobbfamilien, tilknyttes ikonet:

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

Vise at en del er opptatt

IWorkbenchSiteProgressService inneholder programmeringsgrensesnitt for planleggingsjobber som kan endre utseendet til en arbeidsbenkdel mens jobben kjøres. Hvis plugin-modulen kjører bakgrunnsoperasjoner som påvirker tilstanden til en del, kan du planlegge jobben via delen og brukeren får tilbakemelding om at delen er opptatt. 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 */);

Fremdriftsegenskaper for jobber

Arbeidsbenken definerer fremdriftsrelaterte egenskaper for jobber i IProgressConstants . Disse kan brukes for å kontrollere hvordan jobben vises i fremdriftsvisningen. Disse kan brukes til å angi fremdriftsvisningen for å beholde (IProgressConstants#KEEP_PROPERTY) jobben i visningen etter at den er fullført, eller bare beholde en (IProgressConstants#KEEPONE_PROPERTY) jobb om gangen i visningen. Du kan også knytte en handling (IProgressConstants#ACTION_PROPERTY) til en jobb. Når det er tilknyttet en jobb til en handling, viser fremdriftsvisningen en hyperlink slik at brukeren kan kjøre handlingen. Du kan finne ut om en brukerjobb vises i fremdriftsdialogboksen (IProgressConstants#PROPERTY_IN_DIALOG). Når en handling er tilgjengelig, vises et tips nederst til høyre på statuslinjen. Eksempelet nedenfor bruker disse egenskapene:

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

Arbeidsbenkjobber

Der det er mulig skal tidkrevende operasjoner utføres utenfor en brukergrensesnittråd. Dette kan imidlertid ikke alltid unngås når formålet med operasjonen er å oppdatere brukergrensesnittet. Trådbehandlingsspørsmål beskriver hvordan dette kan gjøres ved hjelp av SWT Display. Arbeidsbenken definerer en spesialjobb, UIJob, som har en kjøringsmetode som kjøres i en SWT asyncExec. Subklasser for UIJob skal implementere metoden runInUIThread i stedet for metoden run.

WorkbenchJob utvider UIJob slik at jobben bare kan planlegges eller kjøres når arbeidsbenken kjører. Som alltid bør du unngå omfattende arbeid i brukergrensesnittråden fordi brukergrensesnittet ikke oppdateres så lenge brukergrensesnittjobben eksisterer.