MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Sarcini de continuare

Sarcinile de continuare sau continuation tasks permit definirea sarcinilor care se execută după finalizarea altor sarcini. Astfel, putem lansa mai multe sarcini după finalizarea uneia, putem stabili condițiile pentru lansarea acestora și putem transmite date din sarcina anterioară în următoarea.

Sarcinile de continuare sunt similare cu metodele de callback, dar sunt de fapt sarcini obișnuite Task. Să vedem un exemplu:

Task task1 = new Task(() =>
{
   Console.WriteLine($"Id-ul sarcinii: {Task.CurrentId}");
});

// sarcină de continuare - task2 se execută după task1
Task task2 = task1.ContinueWith(PrintTask);

task1.Start();

// așteptăm finalizarea celei de-a doua sarcini
task2.Wait();
Console.WriteLine("Sfârșitul metodei Main");

void PrintTask(Task t)
{
   Console.WriteLine($"Id-ul sarcinii: {Task.CurrentId}");
   Console.WriteLine($"Id-ul sarcinii anterioare: {t.Id}");
   Thread.Sleep(3000);
}

Prima sarcină este definită folosind o expresie lambda care afișează doar id-ul acestei sarcini. A doua sarcină - sarcina de continuare - este definită folosind metoda ContinueWith, care primește ca parametru un delegat Action<Task>. Astfel, metoda PrintTask, care este transmisă în apelul ContinueWith, trebuie să accepte un parametru de tip Task.

Prin transmiterea în metodă a parametrului Task, putem accesa diverse proprietăți ale sarcinii anterioare, cum ar fi id-ul acesteia.

După finalizarea sarcinii task1, sarcina task2 va fi lansată imediat. Ieșire pe consolă a programului:

Id-ul sarcinii: 1
Id-ul sarcinii: 2
Id-ul sarcinii anterioare: 1
Sfârșitul metodei Main

De asemenea, putem transmite rezultatul specific al sarcinii anterioare:

Task<int> sumTask = new Task<int>(() => Sum(4, 5));

// sarcină de continuare
Task printTask = sumTask.ContinueWith(task => PrintResult(task.Result));

sumTask.Start();

// așteptăm finalizarea celei de-a doua sarcini
printTask.Wait();
Console.WriteLine("Sfârșitul metodei Main");

int Sum(int a, int b) => a + b;
void PrintResult(int sum) => Console.WriteLine($"Suma: {sum}");

În acest caz, sarcina sumTask execută metoda Sum și returnează rezultatul acesteia. Sarcina printTask este sarcina de continuare, care se execută imediat după sumTask și primește rezultatul acesteia. Astfel, în apelul:

Task printTask = sumTask.ContinueWith(task => PrintResult(task.Result));

Parametrul task din expresia lambda reprezintă efectiv sarcina sumTask, din care extragem rezultatul.

În mod similar, putem construi un lanț de sarcini care se execută secvențial:

Task task1 = new Task(() => Console.WriteLine($"Sarcina curentă: {Task.CurrentId}"));

// sarcină de continuare
Task task2 = task1.ContinueWith(t =>
   Console.WriteLine($"Sarcina curentă: {Task.CurrentId}  Sarcina anterioară: {t.Id}"));

Task task3 = task2.ContinueWith(t =>
   Console.WriteLine($"Sarcina curentă: {Task.CurrentId}  Sarcina anterioară: {t.Id}"));

Task task4 = task3.ContinueWith(t =>
   Console.WriteLine($"Sarcina curentă: {Task.CurrentId}  Sarcina anterioară: {t.Id}"));

task1.Start();

task4.Wait();   // așteptăm finalizarea ultimei sarcini
Console.WriteLine("Sfârșitul metodei Main");

Aici, sarcinile task1, task2, task3 și task4 se execută una după alta. Ieșire pe consolă a programului:

Sarcina curentă: 1
Sarcina curentă: 2  Sarcina anterioară: 1
Sarcina curentă: 3  Sarcina anterioară: 2
Sarcina curentă: 4  Sarcina anterioară: 3
Sfârșitul metodei Main
← Lecția anterioară Lecția următoare →