Delen via


Taakafhankelijkheden maken om taken uit te voeren die afhankelijk zijn van andere taken

Met Batch-taakafhankelijkheden maakt u taken die zijn gepland voor uitvoering op rekenknooppunten na voltooiing van een of meer bovenliggende taken. U kunt bijvoorbeeld een taak maken waarmee elk frame van een 3D-film wordt weergegeven met afzonderlijke, parallelle taken. Met de laatste taak worden de gerenderde frames pas samengevoegd in de volledige film nadat alle frames zijn gerenderd. Met andere woorden, de laatste taak is afhankelijk van de vorige bovenliggende taken.

Enkele scenario's waarin taakafhankelijkheden nuttig zijn, zijn onder andere:

  • Workloads in mapReduce-stijl in de cloud.
  • Taken waarvan de gegevensverwerkingstaken kunnen worden uitgedrukt als een gerichte acyclische grafiek (DAG).
  • Pre-rendering- en post-renderingprocessen, waarbij elke taak moet worden voltooid voordat de volgende taak kan beginnen.
  • Elke andere taak waarin downstreamtaken afhankelijk zijn van de uitvoer van upstream-taken.

Afhankelijke taken worden standaard pas gepland voor uitvoering nadat de bovenliggende taak is voltooid. U kunt desgewenst een afhankelijkheidsactie opgeven om het standaardgedrag te overschrijven en de afhankelijke taak uit te voeren, zelfs als de bovenliggende taak mislukt.

In dit artikel wordt besproken hoe u taakafhankelijkheden configureert met behulp van de Batch .NET-bibliotheek . We laten u eerst zien hoe u taakafhankelijkheid van uw taken inschakelt en vervolgens laat zien hoe u een taak met afhankelijkheden configureert. We beschrijven ook hoe u een afhankelijkheidsactie opgeeft om afhankelijke taken uit te voeren als het bovenliggende item mislukt. Ten slotte bespreken we de afhankelijkheidsscenario's die Batch ondersteunt.

Taakafhankelijkheden inschakelen

Als u taakafhankelijkheden in uw Batch-toepassing wilt gebruiken, moet u eerst de taak configureren voor het gebruik van taakafhankelijkheden. Schakel deze in Batch .NET in op uw CloudJob door de eigenschap UsesTaskDependencies in te stellen op true:

CloudJob unboundJob = batchClient.JobOperations.CreateJob( "job001",
    new PoolInformation { PoolId = "pool001" });

// IMPORTANT: This is REQUIRED for using task dependencies.
unboundJob.UsesTaskDependencies = true;

In het voorgaande codefragment is batchClient een exemplaar van de BatchClient-klasse .

Afhankelijke taken maken

Als u een taak wilt maken die afhankelijk is van de voltooiing van een of meer bovenliggende taken, kunt u opgeven dat de taak 'afhankelijk is van' de andere taken. Configureer in Batch .NET de eigenschap CloudTask.DependsOn met een exemplaar van de klasse TaskDependencies :

// Task 'Flowers' depends on completion of both 'Rain' and 'Sun'
// before it is run.
new CloudTask("Flowers", "cmd.exe /c echo Flowers")
{
    DependsOn = TaskDependencies.OnIds("Rain", "Sun")
},

Met dit codefragment maakt u een afhankelijke taak met taak-id 'Bloemen'. De taak 'Bloemen' is afhankelijk van taken 'Regen' en 'Zon'. Taak 'Bloemen' wordt alleen gepland om te worden uitgevoerd op een rekenknooppunt nadat taken 'Regen' en 'Zon' zijn voltooid.

Notitie

Standaard wordt een taak beschouwd als voltooid wanneer deze zich in de voltooide status bevindt en de afsluitcode ervan is 0. In Batch .NET betekent dit dat de eigenschapswaarde CloudTask.State is Completed en dat de eigenschapswaarde TaskExecutionInformation.ExitCode van CloudTask is0. Zie de sectie Afhankelijkheidsacties als u wilt weten hoe u dit kunt wijzigen.

Afhankelijkheidsscenario's

Er zijn drie basisscenario's voor taakafhankelijkheid die u in Azure Batch kunt gebruiken: een-op-een-, een-op-veel- en taak-id-bereikafhankelijkheid. Deze drie scenario's kunnen worden gecombineerd om een vierde scenario te bieden: veel-op-veel.

Scenario Opmerking Illustratie
Individuele taakB is afhankelijk van taakA-taakB

wordt pas gepland voor uitvoering als taakA is voltooid

Diagram van het een-op-een-taakafhankelijkheidsscenario.
Een-op-veel taskC is afhankelijk van zowel taskA als taskB

taskC wordt pas gepland voor uitvoering als zowel taakA als taakB zijn voltooid

Diagram van het een-op-veel-taakafhankelijkheidsscenario.
Taak-id-bereik taakD is afhankelijk van een reeks taken

die niet worden gepland voor uitvoering totdat de taken met id's 1 tot en met 10 zijn voltooid

Diagram met het taak-id-bereik van het taakafhankelijkheidsscenario.

Tip

U kunt veel-op-veel-relaties maken, zoals waar taken C, D, E en F elk afhankelijk zijn van taken A en B. Dit is bijvoorbeeld handig in geparallelliseerde voorverwerkingsscenario's waarbij uw downstreamtaken afhankelijk zijn van de uitvoer van meerdere upstream-taken.

In de voorbeelden in deze sectie wordt een afhankelijke taak pas uitgevoerd nadat de bovenliggende taken zijn voltooid. Dit gedrag is het standaardgedrag voor een afhankelijke taak. U kunt een afhankelijke taak uitvoeren nadat een bovenliggende taak mislukt door een afhankelijkheidsactie op te geven om het standaardgedrag te overschrijven.

Individuele

In een een-op-een-relatie is een taak afhankelijk van de geslaagde voltooiing van één bovenliggende taak. Als u de afhankelijkheid wilt maken, geeft u één taak-id op voor de statische methode TaskDependencies.OnId wanneer u de eigenschap CloudTask.DependsOn vult.

// Task 'taskA' doesn't depend on any other tasks
new CloudTask("taskA", "cmd.exe /c echo taskA"),

// Task 'taskB' depends on completion of task 'taskA'
new CloudTask("taskB", "cmd.exe /c echo taskB")
{
    DependsOn = TaskDependencies.OnId("taskA")
},

Eén-op-veel

In een een-op-veel-relatie is een taak afhankelijk van de voltooiing van meerdere bovenliggende taken. Als u de afhankelijkheid wilt maken, geeft u een verzameling specifieke taak-id's op voor de statische methode TaskDependencies.OnIds wanneer u de eigenschap CloudTask.DependsOn vult.

// 'Rain' and 'Sun' don't depend on any other tasks
new CloudTask("Rain", "cmd.exe /c echo Rain"),
new CloudTask("Sun", "cmd.exe /c echo Sun"),

// Task 'Flowers' depends on completion of both 'Rain' and 'Sun'
// before it is run.
new CloudTask("Flowers", "cmd.exe /c echo Flowers")
{
    DependsOn = TaskDependencies.OnIds("Rain", "Sun")
},

Belangrijk

Het maken van uw afhankelijke taak mislukt als de gecombineerde lengte van bovenliggende taak-id's groter is dan 64000 tekens. Als u een groot aantal bovenliggende taken wilt opgeven, kunt u in plaats daarvan een taak-id-bereik gebruiken.

Taak-id-bereik

In een afhankelijkheid van een bereik van bovenliggende taken is een taak afhankelijk van de voltooiing van taken waarvan de id's binnen een bereik liggen dat u opgeeft.

Als u de afhankelijkheid wilt maken, geeft u de eerste en laatste taak-id's in het bereik op voor de statische methode TaskDependencies.OnIdRange wanneer u de eigenschap CloudTask.DependsOn vult.

Belangrijk

Wanneer u taak-id-bereiken voor uw afhankelijkheden gebruikt, worden alleen taken met id's die gehele getallen vertegenwoordigen geselecteerd door het bereik. Het bereik 1..10 selecteert bijvoorbeeld taken 3 en 7, maar niet 5flamingoes.

Voorloopnullen zijn niet significant bij het evalueren van bereikafhankelijkheden, dus taken met tekenreeks-id's 404 en 004 bevinden zich allemaal binnen het bereik, omdat ze allemaal worden behandeld als taak4, de eerste die moet worden voltooid, voldoet aan de afhankelijkheid.

Om de afhankelijke taak uit te voeren, moet elke taak in het bereik voldoen aan de afhankelijkheid door te voltooien of door een fout te voltooien die is toegewezen aan een afhankelijkheidsactie die is ingesteld op Voldoen.

// Tasks 1, 2, and 3 don't depend on any other tasks. Because
// we will be using them for a task range dependency, we must
// specify string representations of integers as their ids.
new CloudTask("1", "cmd.exe /c echo 1"),
new CloudTask("2", "cmd.exe /c echo 2"),
new CloudTask("3", "cmd.exe /c echo 3"),

// Task 4 depends on a range of tasks, 1 through 3
new CloudTask("4", "cmd.exe /c echo 4")
{
    // To use a range of tasks, their ids must be integer values.
    // Note that we pass integers as parameters to TaskIdRange,
    // but their ids (above) are string representations of the ids.
    DependsOn = TaskDependencies.OnIdRange(1, 3)
},

Afhankelijkheidsacties

Standaard wordt een afhankelijke taak of set taken alleen uitgevoerd nadat een bovenliggende taak is voltooid. In sommige scenario's wilt u mogelijk afhankelijke taken uitvoeren, zelfs als de bovenliggende taak mislukt. U kunt het standaardgedrag overschrijven door een afhankelijkheidsactie op te geven die aangeeft of een afhankelijke taak in aanmerking komt voor uitvoering.

Stel dat een afhankelijke taak wacht op gegevens van de voltooiing van de upstream-taak. Als de upstream-taak mislukt, kan de afhankelijke taak mogelijk nog steeds worden uitgevoerd met oudere gegevens. In dit geval kan een afhankelijkheidsactie opgeven dat de afhankelijke taak in aanmerking komt voor uitvoering, ondanks het mislukken van de bovenliggende taak.

Een afhankelijkheidsactie is gebaseerd op een afsluitvoorwaarde voor de bovenliggende taak. U kunt een afhankelijkheidsactie opgeven voor een van de volgende afsluitvoorwaarden:

  • Wanneer er een preverwerkingsfout optreedt.
  • Wanneer er een fout optreedt bij het uploaden van bestanden. Als de taak wordt afgesloten met een afsluitcode die is opgegeven via exitCodes of exitCodeRanges en er vervolgens een fout optreedt bij het uploaden van bestanden, heeft de actie die is opgegeven door de afsluitcode voorrang.
  • Wanneer de taak wordt afgesloten met een afsluitcode die is gedefinieerd door de eigenschap ExitCodes .
  • Wanneer de taak wordt afgesloten met een afsluitcode die binnen een bereik valt dat is opgegeven door de eigenschap ExitCodeRanges .
  • Als de taak wordt afgesloten met een afsluitcode die niet is gedefinieerd door ExitCodes of ExitCodeRanges, of als de taak wordt afgesloten met een preverwerkingsfout en de eigenschap PreProcessingError niet is ingesteld, of als de taak mislukt met een bestandsuploadfout en de eigenschap FileUploadError niet is ingesteld.

Voor .NET worden deze voorwaarden gedefinieerd als eigenschappen van de klasse ExitConditions .

Als u een afhankelijkheidsactie wilt opgeven, stelt u de eigenschap ExitOptions.DependencyAction voor de afsluitvoorwaarde in op een van de volgende opties:

  • Voldoen: Geeft aan dat afhankelijke taken in aanmerking komen voor uitvoering als de bovenliggende taak wordt afgesloten met een opgegeven fout.
  • Blok: Geeft aan dat afhankelijke taken niet in aanmerking komen voor uitvoering.

De standaardinstelling voor de eigenschap DependencyAction is Voldoen aan voor afsluitcode 0 en Blokkeren voor alle andere afsluitvoorwaarden.

Met het volgende codefragment wordt de eigenschap DependencyAction ingesteld voor een bovenliggende taak. Als de bovenliggende taak wordt afgesloten met een voorverwerkingsfout of met de opgegeven foutcodes, wordt de afhankelijke taak geblokkeerd. Als de bovenliggende taak wordt afgesloten met een andere fout dan nul, komt de afhankelijke taak in aanmerking voor uitvoering.

// Task A is the parent task.
new CloudTask("A", "cmd.exe /c echo A")
{
    // Specify exit conditions for task A and their dependency actions.
    ExitConditions = new ExitConditions
    {
        // If task A exits with a pre-processing error, block any downstream tasks (in this example, task B).
        PreProcessingError = new ExitOptions
        {
            DependencyAction = DependencyAction.Block
        },
        // If task A exits with the specified error codes, block any downstream tasks (in this example, task B).
        ExitCodes = new List<ExitCodeMapping>
        {
            new ExitCodeMapping(10, new ExitOptions() { DependencyAction = DependencyAction.Block }),
            new ExitCodeMapping(20, new ExitOptions() { DependencyAction = DependencyAction.Block })
        },
        // If task A succeeds or fails with any other error, any downstream tasks become eligible to run 
        // (in this example, task B).
        Default = new ExitOptions
        {
            DependencyAction = DependencyAction.Satisfy
        }
    }
},
// Task B depends on task A. Whether it becomes eligible to run depends on how task A exits.
new CloudTask("B", "cmd.exe /c echo B")
{
    DependsOn = TaskDependencies.OnId("A")
},

Voorbeeld van code

Het voorbeeldproject TaskDependencies op GitHub demonstreert:

  • Taakafhankelijkheid voor een taak inschakelen.
  • Taken maken die afhankelijk zijn van andere taken.
  • Deze taken uitvoeren op een pool met rekenknooppunten.

Volgende stappen