Aracılığıyla paylaş


ppl iptali

Bu belge iptali paralel Desenler kitaplığının (ppl), paralel iş iptal etmek nasıl ve ne zaman paralel iş iptal belirleme rolünü açıklar.

[!NOT]

Çalışma zamanı özel durumu işlemeyi iptali uygulamak için kullanır.Catch veya değil kodunuzda bu özel durumlarý iþlemek.Buna ek olarak, görevleriniz için işlev gövdelerinde özel durum-güvenli kod yazma öneririz.Örneği için kullanmak Kaynak edinme ise başlatma (RAII) düzeninin bir görevinin gövdesine bir özel durum oluştuğunda kaynakları doğru şekilde işlenmesini sağlarlar.RAII desen cancelable göreve bir kaynak temizlemek için kullandığı tam bir örnek için bkz: İzlenecek yol: Kullanıcı arabirimi akıştan çalışma kaldırma.

Önemli noktalar

  • İptali işbirliği yapan ve iptali için tepki gösteren görev ve iptal isteklerini kodları arasında koordinasyonu ile ilgilidir.

  • Mümkün olduğunda, iş iptal etmek için İptal simgelerini kullanın.Concurrency::cancellation_token iptali belirteci sınıfı tanımlar.

  • İptali simgeleri kullandığınızda kullanın concurrency::cancellation_token_source::cancel iptali başlatmak için yöntem ve concurrency::is_task_cancellation_requested ve concurrency::cancel_current_task iptali için yanıt vermek için İşlevler.

  • İptali hemen ortaya çıkmaz.Görev veya görev grubu iptal edilirse yeni çalışmanın başlamış değil de, etkin iş arayabilir ve iptali için yanıt.

  • Antecedent, görevini iptal belirteci değerine göre devamı devralır.Görev tabanlı devamı hiçbir zaman belirteci, öncül görevin devralır.

  • Kullanım concurrency::cancellation_token:: yok yapıcısını veya götüren işlevini çağırdığınızda yöntemi bir cancellation_token nesne ancak değil istediğiniz işlemi iptal edilemeyecektir olması.Ayrıca, iptal belirtecine iletmeyen, concurrency::task yapıcı veya concurrency::create_task işlevi, o görevin değil iptal edilemeyecektir.

Bu belgede yer alan

  • Paralel iş ağaçları

  • Paralel görevleri iptal etme

    • Paralel iş iptal etmek için İptal bilgisi belirteç kullanma

    • Yöntem paralel iş iptal etmek için İptal'i kullanma

    • Paralel iş iptal etmek için özel durumlar kullanma

  • Paralel algoritmalar iptal etme

  • İptali'ni ne zaman

Paralel iş ağaçları

ppl, görevleri ve görev gruplarını iyi ayarlanmış görevleri ve hesaplamaları yönetmek için kullanır.Form için görev gruplarını iç içe ağaçları paralel çalışma.Paralel iş ağaç aşağıda gösterilmiştir.Bu resimde de tg1 ve tg2 temsil eden Görev grupları; t1, t2, t3, t4, ve t5 Görev grupları gerçekleştiren iş temsil eder.

Paralel çalışma ağacı

Aşağıdaki örnek resimde ağacı oluşturmak için gereken kodu gösterilir.Bu örnekte, tg1 ve tg2 olan concurrency::structured_task_group nesneleri; 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();   
}

Ayrıca concurrency::task_group benzer iş ağacı oluşturmak için sınıf.Concurrency::task sınıfı da ağaç iş kavramı destekler.Ancak, bir task bir bağımlılık ağacı ağacıdır.İçinde bir task ağaç, gelecekteki works tamamlandıktan sonra geçerli çalışma.Görev grubu ağacında önce dış iş iç iş tamamlar.Görevler ve Görev grupları arasındaki farklar hakkında daha fazla bilgi için bkz: Görev paralellik (eşzamanlılık çalışma zamanı).

Top

Paralel görevleri iptal etme

Paralel iş iptal etmek için birden çok yolu vardır.Tercih edilen yolu iptali belirteci kullanmaktır.Görev grupları da destek concurrency::task_group::cancel yöntemi ve concurrency::structured_task_group::cancel yöntemi.Son görev iş işlev gövdesinde istisna yoldur.Seçtiğiniz yöntem ne olursa olsun, iptali hemen oluşmaz anlayın.Görev veya görev grubu iptal edilirse yeni çalışmanın başlamış değil de, etkin iş arayabilir ve iptali için yanıt.

Paralel görevleri iptal etmek daha fazla örnek için bkz: İzlenecek yol: Görevleri ve xml http isteği (IXHR2) kullanarak bağlanma, Nasıl yapılır: iptali için sonu paralel bir döngü kullanın., ve Nasıl yapılır: özel durum için sonu paralel bir döngü işleme kullanın.

Dd984117.collapse_all(tr-tr,VS.110).gifParalel iş iptal etmek için İptal bilgisi belirteç kullanma

task, task_group, Ve structured_task_group sınıfları iptali iptali belirteçleri kullanarak destekler.ppl tanımlayan concurrency::cancellation_token_source ve concurrency::cancellation_token , bu amaç için sınıflar.İş iptal etmek için İptal bilgisi belirteç kullandığınızda, çalışma zamanı bu belirteç abone olan yeni iş başlamıyor.Zaten etkin olan iş onun iptali belirteci izleyebilir ve mümkün olduğunda durdurun.

Çağrı iptali başlatmak için concurrency::cancellation_token_source::cancel yöntemi.Bu yolla iptali için yanıt:

Aşağıdaki örnek görev iptali için ilk temel desenini gösterir.Görev gövde bazen iptal döngü içinde denetler.

// 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 İşlev atar; Bu nedenle, geçerli döngü ya da işlev açıkça dönmek gerek yoktur.

İpucuİpucu

Alternatif olarak, çağrı concurrency::interruption_point işlevini yerine is_task_cancellation_requested ve cancel_current_task.

Çağrı önemlidir cancel_current_task ne zaman size yanıt iptali için görev iptal edildi durumuna geçmeden çünkü.Arama yerine erken dönerseniz cancel_current_task, operasyon için Tamamlandı durumuna geçişleri ve herhangi bir değere göre continuations çalıştırın.

Uyarı notuUyarı

Hiçbir zaman throw task_canceled kodunuzu karşı.Call cancel_current_task onun yerine.

Bir görevi iptal edilmiş durumda sona erdiğinde concurrency::task::get yöntemi atar concurrency::task_canceled.(Bunun tersi olarak, concurrency::task::wait döndüren task_status::canceled ve oluşturması değildir.) Aşağıdaki örnekte, görev tabanlı devamı için bu davranış gösterilmektedir.Öncül görev iptal edildi görev tabanlı devamı her zaman, denir.

// 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.
*/

Açık bir simge ile oluşturulmuş olan kendi öncül görevin belirteci değerine göre continuations devralır çünkü bile öncül görev hala yürütülmektedir continuations hemen iptal edildi durumunu girin.Bu nedenle, öncül görev tarafından iptali atılan herhangi bir özel durum devamı görevler yayılmadı.Her zaman iptali, öncül görevin durumu geçersiz kılar.Aşağıdaki örnek, önceki benzer ancak değerine göre devamı için davranışı göstermektedir.

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.
*/
Uyarı notuUyarı

İptali belirtecine iletmeyen, task yapıcı veya concurrency::create_task işlevi, o görevin değil iptal edilemeyecektir.Buna ek olarak, herhangi bir iç içe geçmiş görevler (diğer bir deyişle, başka bir göreve gövdesinde oluşturulan görevler) kurucuya aynı iptali belirteci geçmesi gereken tüm görevleri aynı anda iptal etmek.

İptali belirteci iptal edildiğinde rasgele kod çalıştırmak isteyebilirsiniz.Örneğin, kullanıcı seçerse, bir İptal düğmesini kullanıcı arabirimi işlemi iptal etmek için kullanıcı başka bir işlem başlayıncaya kadar bu düğme devre.Aşağıdaki örnek, nasıl kullanılacağını gösterir concurrency::cancellation_token::register_callback iptali belirteci iptal ettiğinizde, bir geri arama işlevi kaydetmek için yöntem.

// 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.
*/

Belge Görev paralellik (eşzamanlılık çalışma zamanı) değeri ve görev tabanlı continuations arasındaki farkı açıklar.Sağladığınız değil, bir cancellation_token nesne devamı göreve devamı öncül görevden iptali belirteci aşağıdaki şekillerde devralır:

  • Öncül görev iptali belirteci bir değere göre devamı her zaman devralır.

  • Görev tabanlı devamı asla öncül görev iptali belirteci devralır.Görev tabanlı devamı cancelable yapmak için yalnızca açıkça iptali belirteci geçirmek için yoludur.

Bu davranışlar, hatalı görev (yani, bir istisna atar) etkilenmez.Bu durumda, değerine göre devamı iptal edilir; görev tabanlı devamı iptal edilmedi.

Uyarı notuUyarı

Başka bir göreve (diğer bir deyişle, iç içe geçmiş bir görev) oluşturulan bir görevin üst görev iptali belirteci devralmaz.Yalnızca bir değeri temel alan devamı, öncül görev iptali belirteci devralır.

İpucuİpucu

Kullanım concurrency::cancellation_token:: yok yapıcısını veya götüren işlevini çağırdığınızda yöntemi bir cancellation_token nesnesi ve istemediği işlemi iptal edilemeyecektir olabilir.

Yapıcısı iptali işaretine de sağlayabilir bir task_group veya structured_task_group nesnesi.Bu önemli bir etmen alt görev grupları bu iptali belirteç devral ' dir.Bu kavram kullanarak gösteren bir örnek için concurrency::run_with_cancellation_token işlevini çağırmak için çalıştırmak için parallel_for, bkz: Paralel algoritmalar iptal etme bu belgede daha sonra.

Top

Dd984117.collapse_all(tr-tr,VS.110).gifİptali simgeleri ve görev oluşturma

Concurrency::when_all ve concurrency::when_any işlevleri, ortak desenleri uygulamak için birden çok görevi oluştur yardımcı olabilir.Bu bölümde iptali simgeleri ile Bu iþlevlerin nasýl çalýþtýðýný açıklanmaktadır.

Ya da iptali belirtecine sağlamak ne zaman when_all ve when_any işlevi, işlevi iptali belirtecini yalnızca iptal edildiğinde veya katılımcının birini iptal edilmiş durumda sona ermeden görevleri ya da bir istisna atar iptal eder.

when_all İşlevi bir iptali belirtecine sağlamayan genel işlem oluşturur, her görevden iptali belirteci devralır.Tarafından döndürülen görev when_all bu simgeleri birini iptal edildi ve en az bir katılımcı görevleri henüz başlatılmadı veya çalışan işlemi iptal edildi.Benzer bir davranış oluşur görevlerden birini bir istisna – tarafından döndürülen görev atar when_all bu özel durumla hemen iptal edilir.

Çalışma zamanı tarafından döndürülen görev iptali belirteci seçerse when_any işlev bu görev tamamlandığında.Katılımcı görevlerden hiçbiri için tamamlanmış durumda bitirmek ve görevlerin en az biri bir istisna attı görevlerden birini tamamlamak için seçilen when_any ve kendi belirteç son görev için belirteç olarak seçilir.Birden fazla görev tamamlanmış biterse state, tarafından döndürülen görev when_any görevi sonlandırır tamamlanmış durumda.Görev, böylece, belirteç tamamlama anda değil iptal tamamlanmış bir görevi seçmek çalışma zamanı çalışır dönen when_any daha ileri bir noktada yürütülen diğer görevleri tamamlayabilir olsa hemen iptal edilmedi.

Top

Dd984117.collapse_all(tr-tr,VS.110).gifYöntem paralel iş iptal etmek için İptal'i kullanma

Concurrency::task_group::cancel ve concurrency::structured_task_group::cancel yöntemleri iptal edildi durumuna bir görev grubu ayarlayın.Siz çağrısından sonra cancel, gelecekteki görevleri görev grubu başlamıyor.cancel Birden çok alt görevlere göre yöntemleri çağrılabilir.İptal edilmiş bir görevi neden olan concurrency::task_group::wait ve concurrency::structured_task_group::wait dönmek için yöntemler concurrency::canceled.

Görev grubu iptal edilirse, çalýþma zamaný her alt görevden çağrılarını tetikleyebilir bir kesinti noktası, durum ve etkin görevleri iptal etmek için bir iç özel durum türü yakalamak çalışma zamanı olur.Eşzamanlılık çalışma zamanı özel kesinti noktalarını tanımlamaz; Çalışma Zamanı Modülü için herhangi bir çağrıda oluşabilir.Çalışma zamanı iptali gerçekleştirmek için atan özel durumlarý iþlemek gerekir.Bu nedenle, bir görev gövdesinde bilinmeyen özel durumlarý iþlemek değil.

Alt görev zaman alıcı bir işlem gerçekleştirir ve zamanına çağırmıyor, düzenli olarak iptali için denetleyin ve gerekir zamanında çıkın.Aşağıdaki örnek, ne zaman iş iptal belirlemenin bir yolu gösterir.Görev t4 bir hatayla karşılaştığında üst görev grubu iptal eder.Görev t5 bazen çağıran structured_task_group::is_canceling iptali denetlemek için yöntem.Üst görev grubu iptal edilirse, görev t5 bir ileti yazdırır ve çıkar.

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

Bu örnekte her 100 üzerinde iptali denetlerth görev döngü.Sizin göreviniz gerçekleştirdiği çalışma miktarının ve görevler iptali için yanıt vermesi için gereken ne kadar çabuk iptali için denetleme sıklığını bağlıdır.

Üst görev grubu nesnesi erişimi yoksa, arama concurrency::is_current_task_group_canceling üst görev grubu iptal olup olmadığını belirlemek için işlev.

cancel Yöntemi, yalnızca alt görevleri etkiler.Örneğin, görev grubu iptal tg1 paralel iş ağaç resimde tüm görevler Ağacı'nda (t1, t2, t3, t4, ve t5) etkilenir.İç içe görev grubu iptal ederseniz tg2, yalnızca görevler t4 ve t5 etkilenir.

Aradığınızda cancel yöntemi, tüm alt görev grupları da iptal.Ancak, iptal paralel iş ağacında görev grubunun herhangi bir anne etkilemez.Aşağıdaki örnekler bu paralel iş ağaç resimde üzerinde oluşturarak gösterir.

Bu örneklerin görevle ilgili bir iş işlev oluşturur t4, bir alt görev grubu olan tg2.İş işlevi işlevini çağırır work bir döngü içinde.Herhangi çağırırsanız work başarısız, görevi kendi üst görev grubu iptal eder.Bu görev grubu neden tg2 iptal edildi durumunu, ancak girmek için görev grubu iptal etmez 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;
      }
   }         
});

Görev grubu görev iptal dışında bu ikinci örnek birincinin benzer 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 Sınıfı iş parçacığı için güvenli değil.Bu nedenle, üst yöntemini çağıran bir alt görev structured_task_group nesne belirsiz davranış üretir.Bu kuralın istisnaları structured_task_group::cancel ve concurrency::structured_task_group::is_canceling yöntemleri.Alt görev üst görev grubu iptal etmek ve iptali denetlemek için bu yöntemleri çağırabilir.

Uyarı notuUyarı

Bir alt öğesi çalışacak bir görev grubu tarafından gerçekleştirilen iş iptal etmek için İptal belirteci kullanabilirsiniz, ancak bir task nesnesini kullanamazsınız task_group::cancel veya structured_task_group::cancel iptal etmek için yöntemler task görev grubu içinde çalışan nesneler.

Top

Dd984117.collapse_all(tr-tr,VS.110).gifParalel iş iptal etmek için özel durumlar kullanma

İptali simgeleri kullanımını ve cancel yöntemi özel durum işleme paralel iş ağaç iptal etme sırasında daha verimlidir.İptali belirteçleri ve cancel yöntemi, yukarıdan aşağıya doğru bir biçimde görev ve tüm alt görevleri iptal.Bunun tersi olarak, özel durum işleme aşağıdan yukarıya bir biçimde çalışır ve özel durum yukarı doğru yayar gibi her alt görev grubu bağımsız olarak iptal etmelisiniz.Konuyu Özel durum işleme eşzamanlılık çalışma zamanında özel durumlar eşzamanlılık çalışma zamanı hataları iletişim kurmak için nasıl kullandığını açıklar.Bununla birlikte, tüm özel durumları bir hata gösterir.Örneğin, sonuç bulduğunda arama algoritması, ilişkili görevini iptal.Ancak, daha önce de belirttiğimiz gibi özel durum işlemenin kullanmaktan daha az verimli cancel paralel iş iptal etme yöntemi.

Uyarı notuUyarı

Yalnızca gerekli olduğunda paralel iş iptal etmek için özel durumlar'ı kullanmanızı öneririz.İptali simgeleri ve görev grubu cancel daha verimli ve daha az hataya yöntemleri.

Bir görev grubu geçirmek çalışma işlev gövdesinde bir özel durum, çalışma zamanı, özel duruma saklar ve bitirmek görev grubu için bekleyeceği içerik için özel sıralar.Olduğu gibi cancel yöntemi, çalışma zamanı henüz başlatılmamış ve yeni görevleri kabul etmeyen görevler atar.

İkincisi, söz konusu görevi dışında bu üçüncü örnektekine benzer t4 görev grubu iptal etmek için bir istisna atar tg2.Bu örnek kullanır bir try-catch iptali denetimi blok, görev grubu tg2 alt görevlerinin tamamlanması bekler.İlk örnekte olduğu gibi bu görev grubu neden tg2 iptal edildi durumunu, ancak girmek için görev grubu iptal etmez 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;
}

Dördüncü Bu örnek, tüm iş ağaç iptal etmek için özel durum işleme kullanır.Örnek Durum yakalar ne zaman görev grubu tg1 alt görevlerinin ne zaman bitmesini bekler görev grubu tg2 , alt görevler için bekler.İkinci örnekte olduğu gibi bu iki görev grupları, ağaç neden tg1 ve tg2, iptal edildi durumunu girin.

// 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;
}

Çünkü task_group::wait ve structured_task_group::wait yöntemleri, bir alt görevi bir istisna atar, throw, dönüş değeri onlardan aldığınız değil.

Top

Paralel algoritmalar iptal etme

Paralel algoritmalar ppl, örneğin, parallel_for, görev gruplarını oluşturun.Bu nedenle, paralel bir algoritma iptal etmek için kullandýðýnýz teknikleri ayný þekilde çoğunu kullanabilirsiniz.

Aşağıdaki örnekte, paralel bir algoritma iptal etmek için çeşitli yöntemler görülmektedir.

Aşağıdaki örnek run_with_cancellation_token işlevini çağırmak için parallel_for algoritması.run_with_cancellation_token İşlevi argüman olarak token bir iptal bildirimi alır ve eşzamanlı olarak sağlanan iş işlevini çağırır.Görevlere paralel algoritmalar yerleşik olduğundan, bunlar üst görev iptali belirteci devralır.Bu nedenle, parallel_for iptali için yanıt verebilirler.

// 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
*/

Aşağıdaki örnek concurrency::structured_task_group::run_and_wait yöntemini çağırmak için parallel_for algoritması.structured_task_group::run_and_wait Yöntemi, verilen görevi tamamlamak bekler.structured_task_group Nesnesi görevi iptal etmek çalışma işlevi sağlar.

// 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;
}

Bu örnek aşağıdaki çıktıyı üretir.

The task group status is: canceled.

Aşağıdaki örnek iptal etmek için özel durum işleme kullanır bir parallel_for döngü.Çalışma zamanı çağrıyı yapan bağlamı ile özel sıralar.

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

Bu örnek aşağıdaki çıktıyı üretir.

Caught 50

Aşağıdaki örnek, bir Boole bayrağı iptali de koordine etmek için kullanır bir parallel_for döngü.Bu örneği kullanmak değil çünkü her görevin çalıştırdığı cancel genel görevler kümesini iptal etmek için yöntem veya özel durum işleme.Bu nedenle, bu teknik daha iptali mekanizması hesaplama yüke sahip olabilir.

// 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.
   }
});

Her iptali yöntemi diğerlerine göre üstünlükleri vardır.Belirli gereksinimlerinize en uygun yöntemi seçin.

Top

İptali'ni ne zaman

İlgili görevler, grubun her üyesi zamanında çıkabilirsiniz, iptali kullanılması uygundur.Ancak, burada iptali uygulamanız için uygun olmayabilir bazı senaryolar da vardır.Görev iptali katmanlanan olduğundan, belirli bir görevi bloke edilirse, genel görevler kümesini iptal edilecek değil.Görev grubu iptal edildi, örneğin, bir göreve henüz başlatılmamış olması, ancak başka bir etkin görev engelini kaldırır, başlatılmaz.Bu kilitlenme uygulamanızda oluşmasına neden olabilir.Burada iptali kullanımına uygun olmayabilir, ikinci bir örnek görev iptal edildi, ancak onun alt görev boşaltma kaynak gibi önemli bir işlem gerçekleştirir ise geçerlidir.Genel görevler kümesini üst görev iptal edildiğinde iptal edildi çünkü o işlemi çalıştırmaz.Bu noktayı gösterir bir örnek için bkz: Understand how Cancellation and Exception Handling Affect Object Destruction paralel Desenler kitaplığının konusundaki en iyi yöntemler bölümündeki.

Top

İlgili Konular

Başlık

Description

Nasıl yapılır: iptali için sonu paralel bir döngü kullanın.

İptali paralel arama algoritması uygulamak için nasıl kullanılacağını gösterir.

Nasıl yapılır: özel durum için sonu paralel bir döngü işleme kullanın

Nasıl kullanılacağını gösteren task_group temel ağaç yapısı için arama algoritması yazmak için sınıf.

Özel durum işleme eşzamanlılık çalışma zamanında

Görev grupları, basit görevleri ve zaman uyumsuz aracıları tarafından atılan istisnalar çalışma zamanı nasıl işlediğini ve özel durumlar uygulamalarınızda isteklerine nasıl açıklar.

Görev paralellik (eşzamanlılık çalışma zamanı)

Görevleri görev grupları nasıl arasında ilişki ve uygulamalarınızda yapılandırılmış ve yapılandırılmamış görevleri nasıl kullanabileceğinizi açıklar.

Paralel algoritmalar

Aynı anda veri derlemeleri üzerinde çalışmayı gerçekleştirmek paralel algoritmalar açıklar

Paralel Desenler kitaplığının (ppl)

Paralel Desenler kitaplığının genel bakış sağlar.

Reference

Sınıf (eşzamanlılık Runtime) görev

cancellation_token_source sınıfı

cancellation_token sınıfı

task_group sınıfı

structured_task_group sınıfı

parallel_for işlevi