找回密码
 立即注册
查看: 190|回复: 0

Unity冷知识:async/await Task的用法限制和解决

[复制链接]
发表于 2023-1-5 19:48 | 显示全部楼层 |阅读模式
本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明
冷知识1:Unity API不是线程安全的

因此,你应该只在UnitySynchronizationContext中使用async和await Task;
异步Task经常在被调用时分配对象,如果过度使用,可能会导致性能问题。
冷知识2:如果要使用异步任务,你必须:


  • 使用手动创建和处理自己的线程Task.RunAPI
  • 使用默认的SynchronizationContext而不是Unity版本
Unity会用自定义的UnitySynchronizationContext覆盖默认的SynchronizationContext,它在主线程上运行所有的Task(不管是Editor模式还是Play模式下)
冷知识3:Unity不会自动停止运行在托管线程(主线程)上的异步Task,因此必须:

监听Play模式的进入和退出(通过EditorApplication.playModeStateChanged事件委托)
如果这么做了,Unity的脚本API在切换回UnitySynchronizationContext之前,都是不可用的!

  • 关于这个问题和解决方案可参考我的《原神游戏开发》日志:https://www.bilibili.com/video/BV1LA411Q7AN/?spm_id_from=333.999.0.0
冷知识4:在development build打包模式下,在非托管线程运行UnityAPI,会看到如下报错:

UnityException: Internal_CreateGameObject can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.冷知识5:出于性能考量,在不采用development build模式打包时,Unity不会报上述错误,但会因多线程问题造成程序随机崩溃或未知错误!

因此,Unity建议不要在脚本中使用多线程,除非……
冷知识6:要安全的使用多线程,并享受其带来的性能优势,可以使用Unity的Job System


  • 关于Job System的原理和用法,可参考我的技术详解:https://www.bilibili.com/video/BV1yA411Y7ou/?spm_id_from=333.999.0.0
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-25 13:55 , Processed in 0.094543 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表