Unity应用退出时如何等待协程执行完成后再退出并完成Web服务器数据保存
问题原因
Unity的OnApplicationQuit是同步执行的,函数执行完成后Unity会立即开始销毁所有场景对象、终止所有运行逻辑,不会等待协程yield return之后的异步逻辑执行,所以你的网络请求还没完成程序就已经退出了。
解决方案
通过Application.wantsToQuit事件拦截系统默认的退出流程,先执行保存数据的协程,等协程执行完成后再主动调用Application.Quit()退出应用。
具体修改步骤
- 新增退出拦截逻辑,替换原来的
OnApplicationQuit方法
在你项目中的全局管理类(比如GameManager)中添加如下代码:
private bool isProcessingQuit = false; [RuntimeInitializeOnLoadMethod] private static void RegisterQuitHandler() { Application.wantsToQuit += OnTryQuitApplication; } private static bool OnTryQuitApplication() { // 已经在执行退出前的保存流程,允许本次退出 if (Instance.isProcessingQuit) return true; // 阻止默认退出流程,启动保存协程 Instance.StartCoroutine(Instance.SaveDataThenQuit()); return false; } private IEnumerator SaveDataThenQuit() { isProcessingQuit = true; // 等待保存协程执行完成,最多等待5秒避免程序卡住无法退出 float waitTimeout = 5f; bool saveDone = false; StartCoroutine(SaveGameDataAsync(GameManager.Instance.GetSaveData(), () => saveDone = true)); yield return new WaitUntil(() => { waitTimeout -= Time.unscaledDeltaTime; return saveDone || waitTimeout <= 0; }); // 保存完成后主动调用退出 Application.Quit(); }
- 改造原来的同步保存方法为可等待的协程
把原来返回void的SaveGameData改成返回IEnumerator的异步版本,支持等待执行完成:
private IEnumerator SaveGameDataAsync(SaveData saveData, Action onFinish) { try { string jsonString = JsonConvert.SerializeObject(saveData); // 等待用户数据上传协程执行完成 yield return UserController.Instance.SaveGameLogInfo02Async("name", jsonString, timer); } catch (Exception e) { Debug.LogError($"保存数据失败: {e.Message}"); } finally { onFinish?.Invoke(); } }
- 修改UserController中的保存方法,支持外部等待
// 新增异步可等待版本的保存方法 public IEnumerator SaveGameLogInfo02Async(string name, string rawdata, long time) { if (saveGameLogInfoCoroutine02 == null) { saveGameLogInfoCoroutine02 = SaveGameLogInfoCoroutine02(name, rawdata, time); yield return StartCoroutine(saveGameLogInfoCoroutine02); } // 如果已经有正在执行的保存协程,等待它执行完成 else { yield return new WaitUntil(() => saveGameLogInfoCoroutine02 == null); } }
注意事项
- 不要在
OnApplicationQuit中执行任何异步、协程逻辑,该函数执行完成后所有对象都会被销毁,后续逻辑不会被执行 - 超时机制是必要的,避免网络请求失败时程序卡住无法关闭
- 该方案兼容PC、移动端平台,WebGL平台不存在本地退出逻辑不需要适配
内容的提问来源于stack exchange,提问作者doqltl179
相关产品推荐
相关产品推荐

