【发布时间】:2015-06-27 08:22:35
【问题描述】:
我有一个函数调用 Concurrency::create_task 在后台执行一些工作。在该任务中,需要在StreamSocket 类上调用connectAsync 方法,以便将套接字连接到设备。连接设备后,我需要获取对已连接套接字内事物的一些引用(例如输入和输出流)。
因为它是一个异步方法并且会返回一个IAsyncAction,所以我需要在connectAsync 函数上创建另一个我可以等待的任务。这无需等待,但是当我尝试在这个内部任务上wait() 以进行错误检查时会出现复杂情况。
Concurrency::create_task( Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService::FromIdAsync( device_->Id ) )
.then( [ this ]( Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService ^device_service_ )
{
_device_service = device_service_;
_stream_socket = ref new Windows::Networking::Sockets::StreamSocket();
// Connect the socket
auto inner_task = Concurrency::create_task( _stream_socket->ConnectAsync(
_device_service->ConnectionHostName,
_device_service->ConnectionServiceName,
Windows::Networking::Sockets::SocketProtectionLevel::BluetoothEncryptionAllowNullAuthentication ) )
.then( [ this ]()
{
//grab references to streams, other things.
} ).wait(); //throws exception here, but task executes
基本上,我发现创建要连接的初始任务的同一线程(可能是 UI)也执行该任务和内部任务。每当我尝试从外部任务对内部任务调用 .wait() 时,我都会立即收到异常。但是,内部任务将完成并成功连接到设备。
为什么我的异步链在 UI 线程上执行?我怎样才能正确地等待这些任务?
【问题讨论】:
-
您是否尝试过记录异常?它可能包含为什么抛出它的答案。
-
我有,其实不是抛出异常。我似乎无法用任何不全面的
catch(...)来捕捉它。我已经尝试过 platform::exception 以及我能想到的所有数据类型。 -
也试过
void*和nullptr_t? -
我现在有,仍然没有骰子。一切总是在同一个线程上运行,我很确定这是由于 UI 线程上的 .wait() 造成的,因为我过去曾在 UI 线程上直接尝试过 .wait() (偶然)一次或两次并看到了同样的行为。
-
你会用C++11吗?如果是这样,您可以使用
std::current_exception()获取std::exception_ptr,通过将指向它的指针转换为void*,然后转换为unsigned int**或unsigned long long**(32 位或64 位),您可以从中获取至少一些信息),取消引用两次(或 3 次,如果它看起来是一个有效的指针),然后将结果写入std::cout。据说会导致未定义的行为,但指针需要存储在某个地方,对吗?我会说至少值得一试。
标签: multithreading asynchronous c++-cx