2016-12-22 5 views
2

Я пытаюсь присоединиться к двум задачам pplx, используя задачу && operator, где обе подзадачи могут генерировать исключения.Как поймать исключения из нескольких задач в Casablanca

Я понимаю из ppl documentation, что я могу поймать исключение в окончательном, основанном на задании продолжении. Это работает и в Касабланке. Однако я могу уловить только одно исключение в своем последнем продолжении. Если оба подзадачи бросаются, один остается необработанным.

Вот минимальный пример, иллюстрирующий мою проблему:

#include <pplx/pplxtasks.h> 
#include <iostream> 

int main(int argc, char *argv[]) 
{ 
    int a = 0; int b = 0; 

    auto t1 = pplx::create_task([a] { return a+1; }) 
    .then([](int a) { throw std::runtime_error("a"); 
         return a+1; }); 

    auto t2 = pplx::create_task([b] { return b+1; }) 
    .then([](int b) { throw std::runtime_error("b"); 
         return b+1; }); 

    (t1 && t2) 
    .then([] (std::vector<int>) { /*...*/ }) 
    .then([] (pplx::task<void> prev) { 
     try { 
      prev.get(); 
     } catch (std::runtime_error e) { 
      std::cout << "caught " << e.what() << std::endl; 
     } 
    }); 

    std::cin.get(); 
} 

пробном/Загвоздка в состоянии поймать какой из двух исключений происходит первым. Как я могу поймать другого?

ответ

1

Вам нужно будет добавить окончательное продолжение на основе задач для каждой подзадачи. Я бы предложил повторно выбросить любое исключение, которое вы поймаете, однако это будет плохой идеей, так как задача продолжения не понимает, что 2 исключения эквивалентны, см. Ниже пример доказательства.
Выход:
поймал
пойманных окончательным,
поймал б

Кроме того, если вы удалите сон, вы получите «/ точки останова ловушки трассировки» исключение.

#include <pplx/pplxtasks.h> 
#include <iostream> 

int main(int argc, char *argv[]) 
{ 
    int a = 0; int b = 2; 

    auto t1 = pplx::create_task([a] { return a+1; }) 
    .then([](int a) { throw std::runtime_error("a"); return a+1; }) 
    .then([] (pplx::task<int> prev) 
    { 
     int retVal = -1; 
     try 
     { 
      retVal = prev.get(); 
     } 
     catch (std::runtime_error e) 
     { 
      std::cout << "caught " << e.what() << std::endl; 
      throw e; 
     } 

     return retVal; 
    }); 

    auto t2 = pplx::create_task([b] { return b+1; }) 
    .then([](int b) { throw std::runtime_error("b"); return b+1; }) 
    .then([] (pplx::task<int> prev) 
    { 
     int retVal = -1; 
     try 
     { 
      sleep(1); 
      retVal = prev.get(); 
     } 
     catch (std::runtime_error e) 
     { 
      std::cout << "caught " << e.what() << std::endl; 
      throw e; 
     } 

     return retVal; 
    }); 

    (t1 && t2) 
    .then([] (std::vector<int> v) { for(int i : v) { std::cout << i << std::endl; } }) 
    .then([] (pplx::task<void> prev) 
    { 
     try 
     { 
      prev.get(); 
     } 
     catch (std::runtime_error e) 
     { 
      std::cout << "caught final " << e.what() << std::endl; 
     } 
    }).get(); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^