ninja_ken  

关于PPL是什么,可以搜索关键字MSDN PPL了解详情。这里谈一下困扰自己好一阵子的一个地方--task chain中抛出异常的处理,一来可为其他码农同行参考,二来给自己做个记录,以免日后忘却。

Value-based continuation的成功尝试

void testValueBasedContinuation()
{
    concurrency::task<void> task1([] {
        throw std::exception("Hello"); });

    //set a breakpoint here, and see the wcout IS executed
    auto task2 = task1.then([]() {
        std::cout << "continuation" << std::endl;
    });

    try
    {
        task2.wait();
    }
    catch (std::exception& e)
    {
        std::cout << "exception" << std::endl;
    }
}

这里的要点在于,value-based continuation中continuation task的执行一定是在previous task执行完成之后,因此将continuation task用try catch(T-C)保护起来即可。(个人猜测,value-based chain会在同一个线程中执行)

错误的写法包括:

  1. 直接将task1的声明用try catch保护起来
  2. 直接将auto task2一句用try catch保护起来

原因是,声明处并不是task的真正执行的地方,保护起来并没有作用

 导致PPL库抛出如下异常

        ~_ExceptionHolder()
        {
            if (_M_exceptionObserved == 0)
            {
                // If you are trapped here, it means an exception thrown in task chain didn't get handled.
                // Please add task-based continuation to handle all exceptions coming from tasks.
                // this->_M_stackTrace keeps the creation callstack of the task generates this exception.
                _REPORT_PPLTASK_UNOBSERVED_EXCEPTION();
            }
        }

 

 

Task-based continuation的成功尝试

void testTaskBasedContinuation()
{
    concurrency::task<void> task1([] {
        throw std::exception("Hello"); });
    auto task2 = task1.then([](concurrency::task<void>& previous) {
        previous.get();
        std::cout << "continuation" << std::endl;
    });
    try
    {
        task2.wait();
    }
    catch (std::exception& e)
    {
        std::cout << "exception" << std::endl;
    }
}

这里的关键是previous.get()那一行,保证代码会在那里抛出异常(而不是其他的线程,个人猜测).

posted on 2018-12-31 13:11  ninja_ken  阅读(903)  评论(0编辑  收藏  举报