- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
你能告诉我我用来处理用例的方法是否无效吗?如果是,正确的处理方法是什么:
task<int> do_work(int param)
{
// runs some work on a separate thread, returns task with result or throws exception on failure
}
void foo()
{
try
{
auto result_1 = do_work(10000);
auto result_2 = do_work(20000);
// do some extra work
process(result_1.get(), result_2.get());
}
catch (...)
{
// logs the failure details
}
}
因此代码尝试并行执行两个作业,然后处理结果。如果其中一个作业抛出异常,则调用 task::get
将重新抛出异常。如果两个任务都抛出异常,则会出现此问题。在这种情况下,对 task::get
的第一次调用将导致堆栈展开,因此将调用第二个 task
的析构函数,进而导致另一个异常在堆栈展开期间重新抛出,这会导致调用“中止”。
在我遇到这个问题之前,这种方法对我来说似乎完全有效。
最佳答案
简而言之,您有一个未处理(未观察到)的异常,因为在您的一项任务中抛出的异常没有得到 caught by the task, one of its continuations, or the main app ,因为从 task::get 为第一个任务重新抛出的异常会在第二个任务调用 task::get 之前展开堆栈。
更简化的代码显示 std::terminate
被调用是因为任务中抛出的异常没有得到处理。取消注释 result.get()
将阻止调用 std::terminate
,因为 task::get
将重新抛出异常。
#include <pplx/pplx.h>
#include <pplx/pplxtasks.h>
#include <iostream>
int main(int argc, char* argv[])
{
try
{
auto result = pplx::create_task([] ()-> int
{
throw std::exception("task failed");
});
// actually need wait here till the exception is thrown, e.g.
// result.wait(), but this will re-throw the exception making this a valid use-case
std::cout << &result << std::endl; // use it
//std::cout << result.get() << std::endl;
}
catch (std::exception const& ex)
{
std::cout << ex.what() << std::endl;
}
return 0;
}
查看 pplx::details::_ExceptionHandler::~_ExceptionHolder()
中的建议
//pplxwin.h
#define _REPORT_PPLTASK_UNOBSERVED_EXCEPTION() do { \
__debugbreak(); \
std::terminate(); \
} while(false)
//pplxtasks.h
pplx::details::_ExceptionHandler::~_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::get
的第一次调用引发了该任务中抛出的异常,这显然阻止了对 task::get
的第二次调用,因此第二个任务的异常没有得到处理(保持“未观察到”)。
the destructor of the second task will be called and will in turn cause one more exception to be re-thrown during stack unwind which causes 'abort' to be called.
第二个任务的析构函数不会重新抛出它只是调用 std::terminate()(它调用 std::abort())的异常
关于c++ - 并发::任务析构函数导致调用在有效用例中中止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24559197/
我开始考虑在我 future 的项目或重构中实现控制反转容器,我想知道在正确设计依赖项时哪些原则(除了 GoF 模式)可能需要牢记在心。假设我需要构建一个简单的控制台应用程序,如果它可以访问互联网,它
假设我有一个 RxC contingency table 。这意味着有 R 行和 C 列。我想要一个维度为 RC × (R + C − 2) 的矩阵 X,其中包含行的 R − 1 “主效应”以及列的
我正在尝试使用 DKMS 为正在运行的内核 (4.4) 构 build 备树覆盖。我天真的 Makefile 如下: PWD := $(shell pwd) dtbo-y += my-awsome-o
我有一个 sencha touch 项目。我是用 phonegap 2.9 构建的,并且可以正常工作 device.uuid 返回到设备 ID。当我尝试使用 3.1 device.uuid 构建时抛出
我在安装了 Xcode 4.5.1 的 Mt Lion 上运行。 默认情况下,当我构建并部署到 iOS 5.1 设备时,显示会在我旋转设备时旋转,但当我部署到 iOS 6 模拟器或运行 iOS 的 i
我正在尝试使用 Google Analytics Reporting API v4 构建多折线图。 一张图表,其中我按每天的 session 计数为每个设备(台式机/平板电脑/移动设备)设置了一条线。
我一生都无法使用 xcode 组织者“自动设备配置”中的“团队配置配置文件”在 xcode 4.0.1 中将我的应用程序构建到我的 iPad 上。 该应用程序完美地构建到模拟器,但当我构建到 iPad
我是一名优秀的程序员,十分优秀!