如何在UWP的CoreIndependentInputSource指针事件中调用StartDragAsync
解决UWP中CoreIndependentInputSource跨线程调用StartDragAsync的问题
在使用CoreIndependentInputSource获取低延迟指针事件时,事件回调运行在独立输入线程,而StartDragAsync必须在UI线程执行,同时PointerPoint具有线程亲和性,无法跨线程传递使用,会直接触发调用异常。
解决方案
核心思路是不直接传递PointerPoint实例,而是传递指针的唯一标识PointerId,然后在UI线程中通过这个ID重新获取属于当前线程的PointerPoint实例。
代码示例
修改OnPointerPressed方法如下:
void Scenario1_LowLatencyInput::OnPointerPressed(Object^ sender, PointerEventArgs^ args) { // 在输入调度线程中提取PointerId(无线程亲和性,可安全跨线程传递) uint32_t pointerId = args->CurrentPoint->PointerId; this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this, pointerId]() { // 在UI线程中通过PointerId重新生成当前线程的PointerPoint实例 PointerPoint^ uiThreadPoint = PointerPoint::GetCurrentPoint(pointerId); if (uiThreadPoint != nullptr) { // 使用UI线程的PointerPoint调用StartDragAsync DragUIItem->StartDragAsync(uiThreadPoint); } })); }
原理说明
PointerId是全局唯一标识指针设备/触摸点的数值,不具备线程亲和性,可以安全跨线程传递。PointerPoint::GetCurrentPoint会在当前调用线程(此处为UI线程)创建新的PointerPoint实例,该实例完全属于UI线程,符合StartDragAsync的线程要求。- 增加空指针检查,避免因指针状态变化(如用户提前抬手)导致的异常。
扩展处理
如果需要传递更多指针相关信息(如坐标、压力值等),可以在输入线程中将这些数据提取为普通值类型(如float、Point),打包后传递到UI线程,再按需使用,同样可以避开线程亲和性问题。
内容的提问来源于stack exchange,提问作者deba
相关产品推荐
相关产品推荐

