Batchbearbeta resursändringar

När du behöver modifiera resurser på arbetsytan är det viktigt att tänka på att andra insticksprogram kan arbeta med samma resurser. Resurs-APIt tillhandahåller robusta mekanismer för att hålla insticksprogram informerade om ändringar på arbetsytan och för att se till att flera insticksprogram inte ändrar samma resurs samtidigt. Där det är möjligt ska insticksprogrammets modifieringar av arbetsytan batchbearbetas i arbetsenheter i en körbar fil på arbetsytan. Dessa körfiler bidrar till att minska mängden ändringsmeddelanden som genereras av ändringar. De gör det även möjligt för dig att deklarera vilken del av arbetsytan som ska modifieras, så att andra insticksprogram kan utelåsas från att ändra samma del av arbetsytan.

Protokollet för IWorkspaceRunnable är ganska enkelt. En körbar fil på arbetsytan ser ut precis som en långt pågående åtgärd eller plattformsjobb. Det egentliga arbetet utförs i en run-metod, där förloppet rapporteras till den tillhandahållna IProgressMonitor. Kod som ändrar arbetsytan körs i run-metoden.

IWorkspaceRunnable myRunnable = 
	new IWorkspaceRunnable() {
		public void run(IProgressMonitor monitor) throws CoreException {
			//do the actual work in here
			...
		}
}

När det är dags att köra koden ber insticksprogrammet arbetsytan att köra koden för sin räkning. På det här sättet kan arbetsytan generera alla nödvändiga ändringshändelser och se till att två insticksprogram inte modifierar samma resurs samtidigt. (Även om ditt insticksprogram inte använder bakgrundsjobb och samtidighetsramverket till att ändra arbetsytan, kan andra insticksprogram göra det.)

Schemaläggningsregler och låsning

Protokollet IWorkspace används till att köra en körbar fil på arbetsytan. Den föredragna tekniken är att använda den långa formen av run-metoden som tillhandahåller en schemaläggningsregel och anger hur resursändringshändelser sänds ut.

Genom att ange en schemaläggningsregel när du kör en körbar fil på arbetsytan kan arbetsytan avgöra huruvida resursändringarna hamnar i konflikt med de arbetsyteändringar som uppstår i andra trådar. (Se Schemaläggningsregler för en översikt av schemaläggningsregler och protokollet ISchedulingRule.) Lyckligtvis innehåller protokollet IResource protokollet för ISchedulingRule, vilket betyder att en resurs ofta kan användas som en schemaläggningsregel för sig själv.

Förvirrande? Lite kod kan hjälpa till att förtydliga denna punkt. Anta att ditt insticksprogram gör sig redo att modifiera några resurser i ett visst projekt. Det kan använda projektet själv som schemaläggningsregel för att utföra ändringarna. Följande kodstycke kör den körbara filen på arbetsytan som vi skapade tidigare:

IWorkspace workspace = ResourcesPlugin.getWorkspace();
workspace.run(myRunnable, myProject, IWorkspace.AVOID_UPDATE, null);

Den körbara filen skickas till arbetsytan, följt av det projekt som koden ändrar. Detta talar om för arbetsytan att alla ändringar i den körbara filen begränsas till myProject. Alla begäran av andra trådar att ändra myProject spärras tills denna körbara fil har slutförts. På samma sätt spärrar detta anrop om en annan tråd redan modifierar myProject. Genom att ange vilken del av resursträdet som ska modifiera av den körbara filen tillåter du att andra trådar fortsätter modifiera andra delar av arbetsytan. Det är viktigt att vara säker på att din resursregel matchar det arbete som utförs i den körbara filen. När en schemaläggningregel som inte är null används utlöser alla försök att få åtkomst till en resurs utanför schemaläggningsregelns omfattning ett undantag.

Det finns två specialregler för schemaläggning som det är viktigt att ta hänsyn till. För det första, om du använder en förekomst av IWorkspaceRoot som schemaläggningsregel innebär det att din tråd blockerar åtkomst till alla resurser i trädet. Medan rotregeln används i en tråd kan ingen annan tråd ändra arbetsytan. Omvänt gäller att regeln null anger att tråden inte blockerar åtkomst till några resurser i trädet. Medan en tråd med regeln null själv kan ändra arbetsytan förhindras inte andra trådar från att göra ändringar. Schemaläggningsreglerna IWorkspaceRoot och null upptar motsatta ytterpositioner i samtidighetsspektrumet. Med IWorkspaceRoot förekommer ingen samtidighet och bara en tråd åt gången kan ändra arbetsytan. Regeln null ger maximal samtidighet eftersom alla trådar kan ändra arbetsytan samtidigt.

Den tredje parametern till metoden run anger huruvida ev. periodiska resursändringshändelser ska sändas ut under anropets omfattning. Genom att använda IWorkspace.AVOID_UPDATE ber du plattformen undertrycka alla resursändringshändelser under tiden som den körbara filen körs och att sända ut en händelse åt gången i slutet av ändringarna. Under det här anropet anses alla andra körbara filer som skapas i den körbara filen vara en del av den överordnade batchåtgärden. Resursändringar som görs i dessa körbara filer visas i den överordnade resursens ändringsmeddelande.

Resursregelfabrik

I exemplet ovan antar vi att koden inuti vår körbara fil bara ändrade resurser i ett visst projekt. Detta gjorde det väldigt enkelt att ange en schemaläggningsregel för den körbara filen. I praktiken kan det vara svårare att beräkna vilka delar av arbetsytan som påverkas av en viss ändring. Om du t.ex. flyttar en resurs från ett projekt till ett annat påverkas båda projekten. IResourceRuleFactory kan användas till att hjälpa till att beräkna en lämplig resursregel för vissa typer av resursändringar. Du kan hämta en resursregelfabrik från själva arbetsytan.

IWorkspace workspace = ResourcesPlugin.getWorkspace();
IResourceRuleFactory ruleFactory = workspace.getRuleFactory();

Fabriken kan tillhandahålla regler lämpliga för många typer av åtgärder. Om din körbara fil flyttar en resurs från en plats till en annan kan den erhålla en regel lämplig för denna åtgärd:

ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource);
workspace.run(myRunnable, movingRule, IWorkspace.AVOID_UPDATE, null);

Se javadoc för IResourceRuleFactory för en lista över tillgängliga regler. Resursernas insticksprogram använder dessa regler själv till att implementera de flesta resursåtgärder. En titt på koden som hänvisar till dessa regelmetoder hjälper till att visa hur de används i praktiken.

Flera regler kan kombineras med MultiRule.

ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource);
ISchedulingRule modifyRule = ruleFactory.modifyResource(destinationResource);
workspace.run(myRunnable, MultiRule.combine(movingRule, modifyRule), IWorkspace.AVOID_UPDATE, null);

Ignorera reglerna

Den korta formen av run-metoden i IWorkspace är också tillgänglig. Den behålls för bakåtkompatibilitet. Den korta formen innehåller inte någon regel eller uppdateringsflagga.

workspace.run(myRunnable, null);

är samma sak som att anropa

workspace.run(myRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, null);

Genom att ange arbetsytans rot som schemaläggningsregel placeras ett lås på hela arbetsytan tills den körbara filen är slutförd. Detta är det mest konservativa sättet att utföra en arbetsyteuppdatering, men det är inte så vänligt mot andra samtidighetsmedvetna insticksprogram.