promise-cpp
promise-cpp copied to clipboard
嵌套promise在析构时候会抛异常
test0.cpp中有如下示例
.then([&next](){
output_func_name();
next= newPromise([](Defer d) {
output_func_name();
//尝试调用d.resolve(1, 'c');
});
//尝试调用 next.resolve();,或next.resolve(1, 'c');
//Will call next.resole() or next.reject() later
//throw 33;
//next.reject(55, 66);
return next;
})
如果增加next.resolve();或者d.resolve(); 会产生bad_any_cast异常,导致promiseHolder->state_ = TaskState::kRejected,在析构时会走到全局异常handler中。
我想通过创建一个新的newPromise的方式,内部切线程异步处理完成后再回调到下个then,这样看起来会有问题。
抓到异常是对的,因为resolve/reject需要下一级的 then/fail 函数捕获。 如果参数类型不一样,无法捕获,就抛异常了。可以这样试下
.then([&next](){
output_func_name();
next = newPromise([](Defer d) {
output_func_name();
});
next.resolve(1, 'c');
return next;
}).then([](int a, char b) {
printf("a = %d, b = %d\n", a, (int)b);
})
或者捕获任意参数类型,可以将 a, b参数去掉
.then([&next](){
output_func_name();
next = newPromise([](Defer d) {
output_func_name();
});
next.resolve(1, 'c');
return next;
}).then([]() {
printf("运行到这里\n");
})
线程切换回来再调用,应该问题不大。 因为:
-
任务链实例析构时,代码会根据需要做出判断,是否要调用 ”全局异常handler“。只要保证任务链实例还在,就不会走到全局异常。
-
next或d内部,都通过shared_ptr的方式,保存了任务链实例。
-
线程切换回来调用,必定要保障 next或d至少有一个(或其复制品)还能访问到。(对比一楼的状况,next和d都被析构了,内部的任务链也析构了,于是走到全局异常。)
感谢你的回复,除了你指出的问题,还有是示例代码后面的then类型未匹配
.then([](int n, char c) {
output_func_name();
printf("n = %d, c = %c\n", (int)n, c);
}).then([](char n) {
output_func_name();
printf("n = %d\n", (int)n);
})
第一个then的return是void和第二个then的入参不一致~,补充上resolve('0')就没有异常了