问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Unity中线程使用指南:实践案例与注意事项

创作时间:
作者:
@小白创作中心

Unity中线程使用指南:实践案例与注意事项

引用
CSDN
1.
https://blog.csdn.net/UnityBoy/article/details/140891256

在Unity开发中,主线程的性能优化是一个永恒的话题。虽然Unity推荐使用协程来避免线程安全问题,但在某些场景下,如需要进行阻塞操作或复杂计算时,使用线程可能是更好的选择。本文将通过一个具体的bug修复案例,介绍在Unity中如何安全地使用线程。

修复线程停止的Bug

在处理一个文件传输的bug时,作者发现了一个关于停止线程的重要问题。最初,作者尝试通过调用Thread.Abort()来停止先前的线程,然后使用Thread.Start()启动具有相同任务函数的新线程。然而,这导致了任务函数中的变量出现了意想不到的结果。

Thread taskThread;

void Task() {
  // 执行某些操作,并拥有局部变量。
  while(true) {
    // ...
  }
}

void StartTask() {
  if (taskThread != null && taskThread.IsAlive)
    taskThread.Abort();
  taskThread = new Thread(Task);
  taskThread.Start();
  // 在Task()中的局部变量出现了一些意想不到的结果
}

// 在Unity的MonoBehaviour中的某处调用
StartTask();

为了解决这个问题,作者采用了更安全的方法:设置一个布尔标志来控制线程的运行状态。这种方法避免了使用Thread.Abort()可能引发的异常问题。

bool runThread = false;
Thread taskThread;
Coroutine startTaskCoroutine;

void Task() {
  // 执行某些操作,并拥有局部变量。
  while(runThread) {
    // ...
  }
}

IEnumerator StartTask() {
  runThread = false;
  while(taskThread != null && taskThread.IsAlive)
    yield return null;

  runThread = true;
  taskThread = new Thread(Task);
  taskThread.Start();
}

// 在Unity的MonoBehaviour中的某处调用
if (startTaskCoroutine != null)
  StopCoroutine(startTaskCoroutine);
startTaskCoroutine = StartCoroutine(StartTask());

结论

在Unity开发中,以下情况更适合使用线程而不是协程:

  1. 需要进行会阻塞主线程的操作
  2. 需要在后台运行的复杂计算
  3. 需要与没有Unity API的原生代码插件通信

使用线程时需要注意以下事项:

  1. 避免在自定义线程中使用Unity API
  2. 使用布尔标志来停止线程,而不是Thread.Abort()
  3. 注意lock()的使用

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号