关于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会在同一个线程中执行)
错误的写法包括:
- 直接将task1的声明用try catch保护起来
- 直接将auto task2一句用try catch保护起来
原因是,声明处并不是task的真正执行的地方,保护起来并没有作用
导致PPL库抛出如下异常
~_ExceptionHolder()
{
if (_M_exceptionObserved == )
{
// 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()那一行,保证代码会在那里抛出异常(而不是其他的线程,个人猜测).