【问题标题】:How to catch exceptions from multiple tasks in Casablanca如何从卡萨布兰卡的多个任务中捕获异常
【发布时间】:2017-05-08 08:47:03
【问题描述】:

我正在尝试使用任务的&& operator 加入两个 pplx 任务,其中两个子任务都可能引发异常。

我从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();
}

try/catch 能够捕获两个异常中最先发生的任何一个。我怎样才能抓住另一个?

【问题讨论】:

    标签: c++ exception casablanca ppl cpprest-sdk


    【解决方案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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-21
      • 2017-04-06
      • 2015-06-02
      • 2016-11-27
      • 2014-06-11
      • 2018-11-14
      • 1970-01-01
      • 2016-02-21
      相关资源
      最近更新 更多