Sdílet prostřednictvím


Zrušení v PPL

Tento dokument vysvětluje roli zrušení paralelní knihovnu vzorků (PPL), jak zrušit paralelní práce a jak lze zjistit, kdy je zrušena paralelní práce.

[!POZNÁMKA]

Zrušení implementovat používá runtime zpracování výjimek.Catch nebo zpracovávat tyto výjimky v kódu.Dále doporučujeme psát kód výjimky bezpečné v orgánech funkce pro úkoly.Můžete například použít Inicializace je získání prostředků (RAII) vzorek zajistit prostředky jsou při do těla úkolu je vyvolána výjimka správně zpracovány.Kompletní příklad, který používá vzorek RAII vyčistit zdroj v cancelable úloh, viz Názorný postup: Odebrání pracovní podproces uživatelského rozhraní.

Klíč bodů

V tomto dokumentu

  • Paralelní stromy práce

  • Zrušení paralelní úlohy

    • Pomocí tokenu zrušení zrušit paralelní práce

    • Pomocí Storno zrušit paralelní pracovní metody

    • Paralelní práci zrušit pomocí výjimky

  • Zrušení paralelní algoritmy

  • Při zrušení nepoužívat

Paralelní stromy práce

PPL používá ke správě uzamykání úkoly a výpočty úkoly a skupiny úloh.Vnoření skupin úloh do formuláře stromy paralelní práce.Následující obrázek znázorňuje paralelní práce stromu.Na tomto obrázku tg1 a tg2 představují skupin úkolů; t1, t2, t3, t4, a t5 představují práce provést skupiny úloh.

Paralelní práce strom

Následující příklad zobrazuje kód nutný k vytvoření stromu na obrázku.V tomto příkladu tg1 a tg2 jsou concurrency::structured_task_group objektů; t1, t2, t3, t4, and t5 are concurrency::task_handle objects.

// task-tree.cpp
// compile with: /c /EHsc
#include <ppl.h>
#include <sstream>
#include <iostream>
#include <sstream>

using namespace concurrency;
using namespace std;

void create_task_tree()
{   
   // Create a task group that serves as the root of the tree.
   structured_task_group tg1;

   // Create a task that contains a nested task group.
   auto t1 = make_task([&] {
      structured_task_group tg2;

      // Create a child task.
      auto t4 = make_task([&] {
         // TODO: Perform work here.
      });

      // Create a child task.
      auto t5 = make_task([&] {
         // TODO: Perform work here.
      });

      // Run the child tasks and wait for them to finish.
      tg2.run(t4);
      tg2.run(t5);
      tg2.wait();
   });

   // Create a child task.
   auto t2 = make_task([&] {
      // TODO: Perform work here.
   });

   // Create a child task.
   auto t3 = make_task([&] {
      // TODO: Perform work here.
   });

   // Run the child tasks and wait for them to finish.
   tg1.run(t1);
   tg1.run(t2);
   tg1.run(t3);
   tg1.wait();   
}

Můžete také použít concurrency::task_group třídy vytvoření stromu podobné práce.Concurrency::task třída také podporuje pojem stromu práce.Však task strom je strom závislostí.V task stromu budoucí works dokončí po aktuální práce.Ve stromové struktuře skupiny úkol dokončí vnitřní práce před vnější práce.Další informace o rozdílech mezi úkoly a skupiny úloh, viz Úkol rovnoběžnosti (souběžnosti Runtime).

Top

Zrušení paralelní úlohy

Paralelní práci zrušit několika způsoby.Preferovaný způsob je zrušení token.Skupiny úkolů také podporu concurrency::task_group::cancel metoda a concurrency::structured_task_group::cancel metoda.Konečné způsobem je k vyvolání výjimky v těle funkce pracovního úkolu.Bez ohledu na to, kterou metodu zvolit pochopit, že zrušení nedojde ihned.Přestože novou práci není spuštěna, pokud úkol nebo skupinu úkolů zrušena, aktivní práce musí kontrolovat a reagovat na zrušení.

Další příklady, které zrušit paralelní úlohy naleznete v tématu Názorný postup: Připojení pomocí úlohy a požadavek HTTP XML (IXHR2), Jak: pomocí zrušení přestávky z paralelní smyčka, a Jak: použití zpracování přestávku na paralelní smyčku z výjimek.

Dd984117.collapse_all(cs-cz,VS.110).gifPomocí tokenu zrušení zrušit paralelní práce

task, task_group, A structured_task_group třídy zrušení pomocí tokenů zrušení podporují.Definuje PPL concurrency::cancellation_token_source a concurrency::cancellation_token třídy pro tento účel.Při použití tokenu zrušení zrušit práci modulu runtime nespustí novou práci, která přihlásí token.Práce, která je již aktivní můžete sledovat jeho zrušení token a při může zastavit.

Iniciovat zrušení, zavolejte concurrency::cancellation_token_source::cancel metoda.Je odpověď na zrušení následujícími způsoby:

Následující příklad ukazuje první základní vzor pro zrušení úkolu.Zrušení uvnitř smyčky občas kontroluje těla úkolu.

// task-basic-cancellation.cpp
// compile with: /EHsc
#include <ppltasks.h>
#include <iostream>
#include <sstream>

using namespace concurrency;
using namespace std;

bool do_work()
{
    // Simulate work.
    wcout << L"Performing work..." << endl;
    wait(250);
    return true;
}

int wmain()
{
    cancellation_token_source cts;
    auto token = cts.get_token();

    wcout << L"Creating task..." << endl;

    // Create a task that performs work until it is canceled.
    auto t = create_task([]
    {
        bool moreToDo = true;
        while (moreToDo)
        {
            // Check for cancellation.
            if (is_task_cancellation_requested())
            {
                // TODO: Perform any necessary cleanup here...

                // Cancel the current task.
                cancel_current_task();
            }
            else 
            {
                // Perform work.
                moreToDo = do_work();
            }
        }
    }, token);

    // Wait for one second and then cancel the task.
    wait(1000);

    wcout << L"Canceling task..." << endl;
    cts.cancel();

    // Wait for the task to cancel.
    wcout << L"Waiting for task to complete..." << endl;
    t.wait();

    wcout << L"Done." << endl;
}

/* Sample output:
    Creating task...
    Performing work...
    Performing work...
    Performing work...
    Performing work...
    Canceling task...
    Waiting for task to complete...
    Done.
*/

cancel_current_task Funkce vyvolá; proto není nutné explicitně vrátit z aktuální smyčky nebo funkce.

Tip

Můžete také zavolat concurrency::interruption_point namísto funkce is_task_cancellation_requested a cancel_current_task.

Je důležité volání cancel_current_task při můžete odpovídat na zrušení, protože ji přechody úloh zrušené stavu.Pokud se brzy vrátíte místo volání cancel_current_task, operace přechody na stav dokončeno a jsou spuštěny všechny založené na hodnotu continuations.

Poznámka k upozorněníUpozornění

Nikdy vyvoláním task_canceled v kódu.Volání cancel_current_task místo.

Po ukončení úkolu zrušené státu concurrency::task::get vyvolá metodu concurrency::task_canceled.(Naopak concurrency::task::wait vrátí task_status::canceled a není vyvolána.) Následující příklad demonstruje toto chování pro pokračování podle úloh.Pokračování podle úloh, se nazývá vždy, i když úkol antecedent je zrušena.

// task-canceled.cpp
// compile with: /EHsc
#include <ppltasks.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
    auto t1 = create_task([]() -> int
    {
        // Cancel the task.
        cancel_current_task();
    });

    // Create a continuation that retrieves the value from the previous.
    auto t2 = t1.then([](task<int> t)
    {
        try
        {
            int n = t.get();
            wcout << L"The previous task returned " << n << L'.' << endl;
        }
        catch (const task_canceled& e)
        {
            wcout << L"The previous task was canceled." << endl;
        }
    });

    // Wait for all tasks to complete.
    t2.wait();
}
/* Output:
    The previous task was canceled.
*/

Protože hodnota založena continuations Pokud byly vytvořeny s explicitní token Zdědit token jejich antecedent úkolu continuations i v případě, že úkol antecedent stále provádí okamžitě zadejte zrušené stát.Proto všechny výjimky, která je vyvolána po zrušení není rozšíření úkolů pokračování antecedent úkolu.Zrušení vždy přepíše stav úkolu antecedent.V následujícím příkladu se podobá předchozí, ale ukazuje chování pro pokračování hodnota založena.

auto t1 = create_task([]() -> int
{
    // Cancel the task.
    cancel_current_task();
});

// Create a continuation that retrieves the value from the previous.
auto t2 = t1.then([](int n)
{
    wcout << L"The previous task returned " << n << L'.' << endl;
});

try
{
    // Wait for all tasks to complete.
    t2.get();
}
catch (const task_canceled& e)
{
    wcout << L"The task was canceled." << endl;
}
/* Output:
    The task was canceled.
*/
Poznámka k upozorněníUpozornění

Pokud neprojde zrušení token task konstruktor nebo concurrency::create_task funkce: Tento úkol je nevratné.Kromě toho musí projít stejným token zrušení konstruktoru vnořené úkoly (to znamená úkoly vytvořené v jiném úkolu) současně zrušit všechny úkoly.

Můžete spustit libovolný kód při zrušení token je zrušena.Pokud uživatel zvolí například Zrušit tlačítko uživatelské rozhraní, chcete-li operaci zrušit, může zakázat tlačítko, dokud uživatel spustí operace.Následující příklad ukazuje použití concurrency::cancellation_token::register_callback metoda zaregistrovat funkci zpětného volání, která se spouští při zrušení token je zrušena.

// task-cancellation-callback.cpp
// compile with: /EHsc
#include <ppltasks.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
    cancellation_token_source cts;
    auto token = cts.get_token();

    // An event that is set in the cancellation callback.
    event e;

    cancellation_token_registration cookie;
    cookie = token.register_callback([&e, token, &cookie]()
    {
        wcout << L"In cancellation callback..." << endl;
        e.set();

        // Although not required, demonstrate how to unregister 
        // the callback.
        token.deregister_callback(cookie);
    });

    wcout << L"Creating task..." << endl;

    // Create a task that waits to be canceled.
    auto t = create_task([&e]
    {
        e.wait();
    }, token);

    // Cancel the task.
    wcout << L"Canceling task..." << endl;
    cts.cancel();

    // Wait for the task to cancel.
    t.wait();

    wcout << L"Done." << endl;
}
/* Sample output:
    Creating task...
    Canceling task...
    In cancellation callback...
    Done.
*/

Dokument Úkol rovnoběžnosti (souběžnosti Runtime) vysvětluje rozdíl mezi continuations hodnotu a úloh.Pokud nezadáte cancellation_token objektu pokračování úkolu pokračování dědí token zrušení antecedent úkol následujícím způsobem:

  • Hodnota založena pokračování vždy dědí token zrušení antecedent úkolu.

  • Pokračování podle úloh nikdy zdědí token zrušení antecedent úkolu.Jediným způsobem, jak vytvořit cancelable pokračování podle úloh je výslovně předat zrušení token.

Těchto chování nejsou ovlivněny úlohy došlo k chybě (tj, vyvolá výjimku).V tomto případě je hodnota založena pokračování zrušena; pokračování podle úloh není zrušeno.

Poznámka k upozorněníUpozornění

Úkol, který je vytvořen v jiném úkolu (jinými slovy, vnořené úlohy) nedědí token zrušení nadřazeného úkolu.Pouze pokračování založené na hodnotu zdědí token zrušení jeho úkolu antecedent.

Tip

Použití concurrency::cancellation_token:: žádný metoda při volání konstruktoru nebo funkce, která trvá cancellation_token objektu a nechcete být nevratné operace.

Můžete také poskytnout token zrušení ke konstruktoru task_group nebo structured_task_group objektu.Důležitým aspektem tohoto je, že skupiny úloh dítě zdědí tento token zrušení.Příklad demonstrující pomocí tohoto konceptu concurrency::run_with_cancellation_token do volání funkce parallel_for, viz Zrušení paralelní algoritmy dále v tomto dokumentu.

Top

Dd984117.collapse_all(cs-cz,VS.110).gifZrušení tokeny a složení úkolu

Concurrency::when_all a concurrency::when_any funkce můžete vytvořit více úkolů pro provádění společných vzorů.Tato část popisuje, jak tyto funkce pracovat zrušení tokeny.

Když poskytnout token zrušení buď when_all a when_any funkce, funkce zruší pouze v případě, že se zruší zrušení token nebo jeden účastník končí ve stavu stornované úkoly či vyvolá výjimku.

when_all Funkce dědí zrušení token z každého úkolu, který composes celkové operace při zrušení token ji nezadáte.Úkol, který se vrátí z when_all je zrušen, když jsou zrušeny všechny tyto tokeny a alespoň jeden z účastníků úkolů nebyla dosud spuštěna nebo je spuštěn.Jedním z úkolů vyvolá výjimku – vrácená z úlohy dojde k podobné chování when_all s výjimkou, že je okamžitě zrušena.

Runtime zvolí token zrušení úkolu, který se vrátí z when_any fungovat po dokončení úkolu.Pokud žádný z účastníků úkoly dokončit stav dokončeno a jeden nebo více úkolů vyvolá výjimku, jedním z úkolů, které způsobilo zvolena Dokončit when_any a jeho token je vybrána jako token pro poslední úkol.Pokud více než jeden úkol je dokončen v vyplněný stavu, úkol, který se vrátí z when_any úkol končí na stav dokončeno.Modul runtime pokusí vybrat dokončeného úkolu, jehož token zrušena v době dokončení tak, aby úkol, který je vrácená z when_any okamžitě zrušena, přestože jiné vykonávající úkoly může dokončit později.

Top

Dd984117.collapse_all(cs-cz,VS.110).gifPomocí Storno zrušit paralelní pracovní metody

Concurrency::task_group::cancel a concurrency::structured_task_group::cancel metody uvedené skupiny úloh zrušené stavu.Po volání cancel, skupiny úloh nespustí budoucí úkoly.cancel Lze volat metody více podřízených úkolů.Zrušené úkolu způsobí, že concurrency::task_group::wait a concurrency::structured_task_group::wait metody vrátit concurrency::canceled.

Pokud skupiny úkolů je zrušena, může spustit volání z jednotlivých podřízených úkolů do modulu runtime bodu přerušení, což způsobuje, že modul runtime generovat a zpracovávat zrušení aktivní úkoly typu vnitřní výjimka.Souběžnost Runtime nedefinuje konkrétní přerušení bodů; může dojít k při volání modulu runtime.Modul runtime musí zpracovat výjimky, které ji k provedení zrušení vyvolá.Proto neukládají neznámý výjimky do těla úkolu.

Pokud podřízený úkol provede časově náročná operace a nevolá do modulu runtime, musí pravidelně kontrolovat zrušení a ukončit včas.Následující příklad ukazuje jeden způsob, jak určit, kdy je zrušena práce.Úkol t4 zruší nadřazené skupiny úloh, když narazí na chybu.Úkol t5 občas volání structured_task_group::is_canceling metody pro kontrolu zrušení.Pokud nadřazená skupina úloh je zrušena, úkol t5 vytiskne zprávu a ukončí.

structured_task_group tg2;

// Create a child task.
auto t4 = make_task([&] {
   // Perform work in a loop.
   for (int i = 0; i < 1000; ++i)
   {
      // Call a function to perform work.
      // If the work function fails, cancel the parent task
      // and break from the loop.
      bool succeeded = work(i);
      if (!succeeded)
      {
         tg2.cancel();
         break;
      }
   }
});

// Create a child task.
auto t5 = make_task([&] {
   // Perform work in a loop.
   for (int i = 0; i < 1000; ++i)
   {
      // To reduce overhead, occasionally check for 
      // cancelation.
      if ((i%100) == 0)
      {
         if (tg2.is_canceling())
         {
            wcout << L"The task was canceled." << endl;
            break;
         }
      }

      // TODO: Perform work here.
   }
});

// Run the child tasks and wait for them to finish.
tg2.run(t4);
tg2.run(t5);
tg2.wait();

V tomto příkladu kontroluje zrušení na každých 100th opakování smyčky úkolu.Frekvence, se kterým je zkontrolovat zrušení závisí na množství práce, kterou úloha provádí a jak rychle potřebujete odpovědět na zrušení úkolů.

Pokud nemáte přístup k objektu skupiny nadřazeného úkolu, zavolejte concurrency::is_current_task_group_canceling funkce určit, zda je zrušena nadřazené skupině úloh.

cancel Metoda ovlivní pouze podřízené úkoly.Například pokud zrušíte úkol skupiny tg1 obrázek stromu paralelní práce, všechny úlohy ve stromu (t1, t2, t3, t4, a t5) jsou ovlivněny.Pokud zrušíte úkol vnořené skupiny tg2, pouze úlohy t4 a t5 jsou ovlivněny.

Při volání cancel metoda, všechny podřízené úkol skupiny jsou rovněž zrušena.Zrušení všech rodičů ve stromu paralelní pracovní skupiny úkolů neovlivňuje.Následující příklady ukazují vytvořením na obrázek stromu paralelní práce.

První z těchto příkladů vytváří funkci práce pro úkol t4, který je podřízeným skupiny úloh tg2.Pracovní funkce volá funkci work ve smyčce.Pokud žádné volání work nezdaří úloha zruší nadřazené skupině úloh.To způsobí, že úkol skupiny tg2 zadejte stav stornované, ale nezrušíte skupiny úloh tg1.

auto t4 = make_task([&] {
   // Perform work in a loop.
   for (int i = 0; i < 1000; ++i)
   {
      // Call a function to perform work.
      // If the work function fails, cancel the parent task
      // and break from the loop.
      bool succeeded = work(i);
      if (!succeeded)
      {
         tg2.cancel();
         break;
      }
   }         
});

Tento druhý příklad podobá první, s výjimkou, že úloha zruší skupiny úloh tg1.This affects all tasks in the tree (t1, t2, t3, t4, and t5).

auto t4 = make_task([&] {
   // Perform work in a loop.
   for (int i = 0; i < 1000; ++i)
   {
      // Call a function to perform work.
      // If the work function fails, cancel all tasks in the tree.
      bool succeeded = work(i);
      if (!succeeded)
      {
         tg1.cancel();
         break;
      }
   }   
});

structured_task_group Třída není podprocesu.Proto podřízeného úkolu který volá metodu nadřazené structured_task_group vytváří objekt nespecifikované chování.Výjimky z tohoto pravidla jsou structured_task_group::cancel a concurrency::structured_task_group::is_canceling metod.Tyto metody zrušit nadřazené skupiny úkolů a zkontrolovat zrušení můžete volat podřízeného úkolu.

Poznámka k upozorněníUpozornění

Přestože token zrušení můžete zrušit práce, která provádí skupiny úloh, která se spouští jako podřízený task objektu nelze použít task_group::cancel nebo structured_task_group::cancel metody zrušit task objekty ve skupině úloh spustit.

Top

Dd984117.collapse_all(cs-cz,VS.110).gifParalelní práci zrušit pomocí výjimky

Použití tokenů zrušení a cancel metody jsou efektivnější než na zrušení stromu práce paralelní zpracování výjimek.Zrušení tokenů a cancel metoda zrušit úkol a všechny podřízené úkoly způsobem shora dolů.Naopak zpracování výjimek způsobem zdola nahoru a musíte zrušit každé skupiny podřízeného úkolu nezávisle jako výjimku rozšíří směrem nahoru.Téma Zpracování výjimek v souběžném běhu vysvětluje použití výjimky komunikovat chyby Runtime souběžnosti.Všechny výjimky však udávající chybu.Algoritmus vyhledávání může být například zrušit jeho přidruženého úkolu při najde výsledek.Jak bylo uvedeno dříve, zpracování výjimek je však méně efektivní než použití cancel metoda zrušit paralelní práce.

Poznámka k upozorněníUpozornění

Doporučujeme používat výjimky paralelní práce pouze v případě potřeby zrušit.Zrušení tokeny a skupiny úloh cancel metody jsou účinnější a méně náchylné k chybě.

Modul runtime vyvoláním výjimky v těle funkce práce, který předáte do skupiny úloh, ukládá výjimku a marshals výjimku z kontextu, který čeká na dokončení skupiny úloh.Stejně jako cancel metoda runtime zahodí všechny úkoly, které ještě nezačalo a nepřijímá nové úkoly.

Druhý, s výjimkou tohoto úkolu se podobá této třetí příklad t4 vyvolá výjimku zrušit skupiny úloh tg2.V tomto příkladu try-catch bloku zkontrolovat zrušení při skupiny úloh tg2 čeká na dokončení jeho podřízených úkolů.Podobně jako v prvním příkladu způsobí, že skupiny úloh tg2 zadejte stav stornované, ale nezrušíte skupiny úloh tg1.

structured_task_group tg2;

// Create a child task.      
auto t4 = make_task([&] {
   // Perform work in a loop.
   for (int i = 0; i < 1000; ++i)
   {
      // Call a function to perform work.
      // If the work function fails, throw an exception to 
      // cancel the parent task.
      bool succeeded = work(i);
      if (!succeeded)
      {
         throw exception("The task failed");
      }
   }         
});

// Create a child task.
auto t5 = make_task([&] {
   // TODO: Perform work here.
});

// Run the child tasks.
tg2.run(t4);
tg2.run(t5);

// Wait for the tasks to finish. The runtime marshals any exception
// that occurs to the call to wait.
try
{
   tg2.wait();
}
catch (const exception& e)
{
   wcout << e.what() << endl;
}

Tento příklad čtvrtý používá zpracování výjimek zrušit práce celého stromu.Příklad úlovky výjimku při úkol skupiny tg1 čekat na dokončení místo při jeho podřízených úkolů úkol skupiny tg2 čeká na jeho podřízených úkolů.Jako druhý příklad to způsobí, že obě skupiny úkolů ve stromu tg1 a tg2, zadat stav stornované.

// Run the child tasks.
tg1.run(t1);
tg1.run(t2);
tg1.run(t3);   

// Wait for the tasks to finish. The runtime marshals any exception
// that occurs to the call to wait.
try
{
   tg1.wait();
}
catch (const exception& e)
{
   wcout << e.what() << endl;
}

Protože task_group::wait a structured_task_group::wait vyvoláním metody při podřízeného úkolu vyvolá výjimku, neobdrží od nich vrácené hodnoty.

Top

Zrušení paralelní algoritmy

Například paralelní algoritmy v PPL, parallel_for, vytvoření skupiny úkolů.Proto můžete mnoho stejných postupů zrušit paralelní algoritmus.

Následující příklady ilustrují několik způsobů, jak zrušit paralelní algoritmus.

V následujícím příkladu run_with_cancellation_token funkci volat parallel_for algoritmus.run_with_cancellation_token Funkce zrušení token jako argument a volá funkci zadané práce synchronně.Protože paralelní algoritmy jsou založeny na úkoly, zdědí token zrušení nadřazeného úkolu.Proto parallel_for může reagovat na zrušení.

// cancel-parallel-for.cpp
// compile with: /EHsc
#include <ppltasks.h>
#include <iostream>
#include <sstream>

using namespace concurrency;
using namespace std;

int wmain()
{
    // Call parallel_for in the context of a cancellation token.
    cancellation_token_source cts;
    run_with_cancellation_token([&cts]() 
    {
        // Print values to the console in parallel.
        parallel_for(0, 20, [&cts](int n)
        {
            // For demonstration, cancel the overall operation 
            // when n equals 11.
            if (n == 11)
            {
                cts.cancel();
            }
            // Otherwise, print the value.
            else
            {
                wstringstream ss;
                ss << n << endl;
                wcout << ss.str();
            }
        });
    }, cts.get_token());
}
/* Sample output:
    15
    16
    17
    10
    0
    18
    5
*/

V následujícím příkladu concurrency::structured_task_group::run_and_wait volání metody parallel_for algoritmus.structured_task_group::run_and_wait Metoda čeká na dokončení zadané úlohy.structured_task_group Objekt umožňuje práci funkci Zrušit úlohu.

// To enable cancelation, call parallel_for in a task group.
structured_task_group tg;

task_group_status status = tg.run_and_wait([&] {
   parallel_for(0, 100, [&](int i) {
      // Cancel the task when i is 50.
      if (i == 50)
      {
         tg.cancel();
      }
      else
      {
         // TODO: Perform work here.
      }
   });
});

// Print the task group status.
wcout << L"The task group status is: ";
switch (status)
{
case not_complete:
   wcout << L"not complete." << endl;
   break;
case completed:
   wcout << L"completed." << endl;
   break;
case canceled:
   wcout << L"canceled." << endl;
   break;
default:
   wcout << L"unknown." << endl;
   break;
}

Tento příklad vytvoří následující výstup.

The task group status is: canceled.

Následující příklad používá zpracování výjimek zrušit parallel_for smyčky.Modul runtime marshals výjimku v kontextu volajícího.

try
{
   parallel_for(0, 100, [&](int i) {
      // Throw an exception to cancel the task when i is 50.
      if (i == 50)
      {
         throw i;
      }
      else
      {
         // TODO: Perform work here.
      }
   });
}
catch (int n)
{
   wcout << L"Caught " << n << endl;
}

Tento příklad vytvoří následující výstup.

Caught 50

Následující příklad používá příznak typu Boolean zrušení v koordinaci parallel_for smyčky.Každý úloha spuštěna, protože tento příklad nepoužívá cancel metoda nebo výjimku zpracování zrušit celkovou sadu úkolů.Tento postup lze tudíž více výpočetní nároky než mechanismus zrušení.

// Create a Boolean flag to coordinate cancelation.
bool canceled = false;

parallel_for(0, 100, [&](int i) {
   // For illustration, set the flag to cancel the task when i is 50.
   if (i == 50)
   {
      canceled = true;
   }

   // Perform work if the task is not canceled.
   if (!canceled)
   {
      // TODO: Perform work here.
   }
});

Každá metoda zrušení má výhody oproti ostatním.Zvolte metodu, která odpovídá vašim konkrétním potřebám.

Top

Při zrušení nepoužívat

Zrušení používání je vhodné, když každý člen skupiny souvisejících úloh lze ukončit včas.Existují však některé scénáře, kde zrušení nemusí být vhodné pro vaše aplikace.Například zrušení úkolu je spolupráce, celkovou sadu úkolů nebude zrušit, pokud je blokován všech jednotlivých úkolů.Například jeden úkol ještě nebyl zahájen, ale je aktivní jiný úkol odblokuje, nebude spuštěn Pokud skupiny úloh je zrušena.To může způsobit zablokování aplikace.Druhý příklad, o kterých nemusí být vhodné použití zrušení je úkol je zrušena, ale jeho podřízeného úkolu provádí důležité operace, například uvolnění prostředku.Protože celkovou sadu úkolů je zrušena, pokud nadřazený úkol je zrušena, operace nebude spuštěn.Příklad ilustruje tento bod, najdete Understand how Cancellation and Exception Handling Affect Object Destruction části Doporučené postupy v tématu paralelní knihovnu vzorků.

Top

Příbuzná témata

Title

Description

Jak: pomocí zrušení přestávky z paralelní smyčka

Ukazuje, jak použít k implementaci algoritmu paralelní hledání zrušení.

Jak: použití zpracování přestávku na paralelní smyčku z výjimek

Použití task_group třídy zápis algoritmu hledání pro základní stromové struktury.

Zpracování výjimek v souběžném běhu

Popisuje způsob zpracování modulu runtime výjimky odsunuté skupin úkolů, lehké úkoly a asynchronní agenti a jak reagovat na výjimky v aplikacích.

Úkol rovnoběžnosti (souběžnosti Runtime)

Popisuje, jak souvisí úkoly skupiny úkolů a používání úkolů nestrukturované a strukturované v aplikacích.

Paralelní algoritmy

Popisuje paralelní algoritmy, které současně provádět práce kolekcí dat.

Paralelní knihovnu vzorků (PPL)

Přehled paralelní knihovnu vzorků.

Odkaz

úkol třídy (souběžnosti Runtime)

Třída cancellation_token_source

Třída cancellation_token

Třída task_group

Třída structured_task_group

parallel_for funkce