About what PPL is, you can search the keyword MSDN PPL for details. Here's a place that has been bothering me for a long time -- the handling of exceptions thrown in the task chain. It can be used as a reference for other coders, and it can make a record for myself to avoid forgetting in the future.
Successful attempt of 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; } }
The point here is that the execution of the continuation task in value based continuation must be completed after the execution of the previous task, so the continuation task can be protected with try catch(T-C). (personal guess: value based chain will be executed in the same thread)
Wrong writing includes:
- Directly protect the declaration of task1 with try catch
- Directly protect the sentence "auto task2" with "try catch"
The reason is that the declaration office is not the place where the task is actually executed, and protection does not work
Cause the PPL library to throw the following exception
~_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(); } }
Successful attempt of 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; } }
The key here is the previous.get() line, which ensures that the code will throw exceptions there (instead of other threads, personal guesses)