线程在调用AccessibleChildren时冻结 我的C++应用程序将使用基于MSDN示例的代码来从多个应用程序中移植MSAA树:
它工作得很好,直到几个月前,我开始注意到,有时线程在AccessibleChildren呼叫时冻结 以下是我对它的了解:线程在调用AccessibleChildren时冻结 我的C++应用程序将使用基于MSDN示例的代码来从多个应用程序中移植MSAA树:,c++,com,iaccessible,C++,Com,Iaccessible,它工作得很好,直到几个月前,我开始注意到,有时线程在AccessibleChildren呼叫时冻结 以下是我对它的了解: 这种情况并不经常发生 它发生在行走不同应用程序的树时 它肯定没有连接到当前节点的子节点数量,因为我已经调试了where bottom callchildCountequal为1的小转储 它发生在不同的PC上 处于这种位置的线程永远不会醒来。一旦冻结发生,线程将保持此状态,直到应用程序重新启动 有时线程在这样的迭代过程中死亡,在这种情况下,我无法捕捉到它的踪迹。应用程序的其余
- 这种情况并不经常发生
- 它发生在行走不同应用程序的树时李>
- 它肯定没有连接到当前节点的子节点数量,因为我已经调试了where bottom call
equal为1的小转储李>childCount
- 它发生在不同的PC上
- 处于这种位置的线程永远不会醒来。一旦冻结发生,线程将保持此状态,直到应用程序重新启动
- 有时线程在这样的迭代过程中死亡,在这种情况下,我无法捕捉到它的踪迹。应用程序的其余部分继续运行,但转储显示给定的线程不再工作,尽管它的任务基本上是带有睡眠的无限循环。我想它和冰柜有关。不知怎么的
--> ntdll.dll!_NtWaitForMultipleObjects@20() Unknown
ntdll.dll!_NtWaitForMultipleObjects@20() Unknown
KERNELBASE.dll!_WaitForMultipleObjectsEx@20() Unknown
kernel32.dll!_WaitForMultipleObjectsExImplementation@20() Unknown
user32.dll!_RealMsgWaitForMultipleObjectsEx@20() Unknown
ole32.dll!CCliModalLoop::BlockFn(void * * ahEvent, unsigned long cEvents, unsigned long * lpdwSignaled) Line 1222 C++
ole32.dll!ModalLoop(CMessageCall * pcall) Line 211 C++
ole32.dll!ThreadSendReceive(CMessageCall * pCall) Line 4979 C++
ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall(CMessageCall * * ppCall) Line 4454 C++
ole32.dll!CRpcChannelBuffer::SendReceive2(tagRPCOLEMESSAGE * pMessage, unsigned long * pstatus) Line 4076 C++
ole32.dll!CCliModalLoop::SendReceive(tagRPCOLEMESSAGE * pMsg, unsigned long * pulStatus, IInternalChannelBuffer * pChnl) Line 899 C++
ole32.dll!CAptRpcChnl::SendReceive(tagRPCOLEMESSAGE * pMsg, unsigned long * pulStatus) Line 583 C++
ole32.dll!CCtxComChnl::SendReceive(tagRPCOLEMESSAGE * pMessage, unsigned long * pulStatus) Line 659 C++
ole32.dll!NdrExtpProxySendReceive(void * pThis, _MIDL_STUB_MESSAGE * pStubMsg) Line 1932 C++
rpcrt4.dll!@NdrpProxySendReceive@4() Unknown
rpcrt4.dll!_NdrClientCall2() Unknown
ole32.dll!ObjectStublessClient(void * ParamAddress, long Method) Line 474 C++
ole32.dll!_ObjectStubless@0() Line 154 Unknown
ole32.dll!CStdMarshal::Begin_RemQIAndUnmarshal1(unsigned short cIIDs, _GUID * pIIDs, tagQICONTEXT * pQIC) Line 4551 C++
ole32.dll!CStdMarshal::Begin_QueryRemoteInterfaces(unsigned short cIIDs, _GUID * pIIDs, tagQICONTEXT * pQIC) C++
ole32.dll!CStdMarshal::QueryRemoteInterfaces(unsigned short cIIDs, _GUID * pIIDs, tagSQIResult * pQIRes) Line 4284 C++
ole32.dll!CStdIdentity::CInternalUnk::QueryMultipleInterfaces(unsigned long cMQIs, tagMULTI_QI * pMQIs) Line 596 C++
ole32.dll!CStdIdentity::CInternalUnk::QueryInterface(const _GUID & riid, void * * ppv) Line 352 C++
ole32.dll!IUnknown_QueryInterface_Proxy(IUnknown * This, const _GUID & riid, void * * ppv) Line 1723 C++
ole32.dll!CoUnmarshalInterface(IStream * pStm, const _GUID & riid, void * * ppv) Line 996 C++
oleacc.dll!UnmarshalInterface(unsigned char const *,unsigned long,struct _GUID const &,void * *) Unknown
oleacc.dll!FreeUpSlot(struct OutstandingObjectEntry *) Unknown
oleacc.dll!_ObjectFromLresult@16() Unknown
oleacc.dll!NativeIAccessibleFromWindow(struct HWND__ *,unsigned long,struct _GUID const &,void * *) Unknown
oleacc.dll!_ORIGINAL_AccessibleObjectFromWindow@16() Unknown
oleacc.dll!_AccessibleObjectFromWindow@16() Unknown
oleacc.dll!GetWindowObject(struct HWND__ *,struct tagVARIANT *) Unknown
oleacc.dll!CClient::Next(unsigned long,struct tagVARIANT *,unsigned long *) Unknown
oleacc.dll!AccWrap_Base::Next(unsigned long,struct tagVARIANT *,unsigned long *) Unknown
oleacc.dll!_AccessibleChildren@20() Unknown
//my recursion ends here
我仍然不知道为什么会发生上述情况,以及如何从代码中保护我的应用程序不受这些影响。我自己认为唯一的解决方案是使用单独的进程,并等待超时。类似,但超时设置为常量(如半秒),而不是
无限
若等待因为进程完成而结束,那个么我会得到它的stdout作为响应(一些带有result的json或类似的东西)。若进程超时,我将简单地终止它以清理其资源
这不是一个完美的解决方案,但它会让我对正在发生的事情有一些控制,我会以某种方式防止内存泄漏等
由于这只是衡量的一半,我很乐意接受任何其他想法来解决我的问题。客户机和服务器是否与同一用户一起运行?此外,MSAA也遭到了相当多的反对。你尝试过UIA吗:我正在使用UIA,但由于我的一些客户端PC不是最新的XP,我不得不保持对MSAA的支持。我不确定用户的情况,但问题的一致性不足以让我假设,例如,有人让internet explorer始终以管理员身份运行,而我的应用程序是普通用户。我能猜到的最接近的一件事是,有问题的程序(比如IE)想要运行下载的文件,而用户访问控制不知何故导致了我的问题,但我对UAC机制还不够熟悉,不知道这是不是真的。