Vuforia跟踪场景下ObjectDisposedException异常解决求助
问题分析与解决方案
核心问题
目标丢失后,已启动的Calculation协程仍会继续执行,此时repeatList已被清空、answerObj已失活,SetRepeatPos()访问列表项时触发ObjectDisposedException。现有方案的核心缺陷是无法实时中断正在执行的协程逻辑,且状态标记的同步性不足。
解决方案
1. 给协程添加实时中断检查
在Calculation协程的关键执行节点(尤其是访问repeatList和answerObj前),增加双重有效性检查,确保协程在状态失效时立即终止:
private IEnumerator Calculation() { // 全局标记失效直接终止 if (!doCalculation) yield break; if (!AreAllOptionsTracked()) { answerImg.gameObject.SetActive(false); model?.SetActive(false); yield break; } isCalculationOn = true; // 实时检查:标记有效 + 对象激活 + 列表非空 if (doCalculation && answerObj != null && answerObj.activeInHierarchy && repeatList.Count > 0) { SetRepeatPos(); } bool isCorrect = CheckOptionOrder(); isCalculationOn = false; }
2. 重构ClearGame与ClearAll逻辑,确保状态同步
放弃固定时长等待,主动等待isCalculationOn变为false,同时调整操作顺序,先确保协程完全停止再清理资源:
private void ClearGame() { doCalculation = false; StopCoroutine(DoCalculation()); // 直接终止外层循环协程 StartCoroutine(ClearAll()); } private IEnumerator ClearAll() { // 等待当前Calculation协程执行完毕 while (isCalculationOn) { yield return null; // 每帧检查,适配协程实际执行时长 } // 先清空列表,再处理对象(避免对象失活后列表仍被访问) repeatList?.Clear(); if (answerObj != null) { answerObj.SetActive(false); answerObj = null; } }
3. 给SetRepeatPos()添加防御性检查
在直接访问repeatList的方法内部增加前置判断,从源头避免异常:
private void SetRepeatPos() { if (repeatList == null || repeatList.Count == 0 || !answerObj.activeInHierarchy) { return; // 无效状态直接返回 } // 原有位置计算逻辑... }
为什么之前的方案无效?
WaitForSeconds/固定等待:无法匹配协程实际执行时长,容易出现时序偏差break/标记判断:仅能终止外层循环,无法中断已进入执行流程的Calculation协程try-catch:虽能捕获异常,但未解决状态不同步的核心矛盾- 数组/执行顺序/委托等:未触及协程执行与状态清理的时序冲突问题
内容的提问来源于stack exchange,提问作者sarthak musale
相关产品推荐
相关产品推荐

