我有一个函数调用Concurrency::create_task在后台执行一些工作。在该任务中,需要在connectAsync
类上调用StreamSocket
方法,以将套接字连接到设备。连接设备后,我需要获取所连接套接字内部内容的一些引用(例如输入和输出流)。
由于它是一个异步方法,并且将返回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线程上执行?如何正确等待这些任务?
最佳答案
通常,您应该避免使用.wait()
并仅继续执行异步链。如果由于某种原因需要阻止,唯一的防呆机制是从后台线程(例如WinRT线程池)显式运行代码。
您可以尝试使用.then()
重载,该重载需要task_options
并传递concurrency::task_options(concurrency::task_continuation_context::use_arbitrary())
,但不能保证延续将在另一个线程上运行;它只是说如果可以的话就可以了-请参阅documentation here。
关于multithreading - C++/CX中的任务上的.wait()引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29750774/