[FA] AB包卸载异步转同步测试

2023-09-28  本文已影响0人  _Walker__

1、环境

2、结论

3、尝试强制阻塞主线程

  既然Unity自己没提供阻塞的接口,我就想是否可以强制把主线程阻塞住,等子线程执行完成后再恢复? 把问题抛给GPT,得到了一个没了解过的工具类,可以完成这个任务,下面介绍下用法。

AutoResetEvent block = new AutoResetEvent(false);
asyncOperation.completed += (ao =>
{
    block.Set();  // 异步操作完成后,恢复主线程
});
block.WaitOne(100000); // 阻塞当前(主)线程,超时时间10s

AutoResetEvent使用说明:

  • 当对象处于非信号状态(non-signaled)时,调用WaitOne()会阻塞当前线程。
    直到收到信号后,释放线程。
  • 构造方法参数
    传true:对象默认处于信号(signaled)状态,第一次调用WaitOne()便不会阻塞线程;
    传false:对象默认处于非信号状态,第一次调用WaitOne()会阻塞线程
  • Set()方法是给对象设置信号,如果有处于阻塞状态的对象,此时会释放线程
  • AutoResetEvent的对象,每次收到信号,释放阻塞线程后,都会把自己的状态重置,变成非信号状态,相当于自动调用了Reset()
  • AutoResetEvent相对应的,还有个ManualResetEvent类。它俩的区别只在于上面一条说的特性,ManualResetEvent不会再收到信号后,自动重置,需要手动调用Reset()才会将对象变为非信号状态。
经测试,此路不通!!!

  执行AsyncOperation asyncOperation = bundle.UnloadAsync(true);之后,如果阻塞了主线程,则资源卸载的操作也不会执行了。无论是同一帧阻塞,还是下一帧阻塞,都是如此。
  并且,阻塞恢复后,异步卸载的时长完全没减少。我测试的时候,执行卸载后,要经过4帧的时间asyncOperation.isDone才会变为true。我把主线程阻塞10s后恢复,Unity还是要执行4帧时间isDone才会变为true。
  为了排除主线程阻塞后,completed回调无法调回来的可能,我还尝试了死循环等待的方式:while(!asyncOperation.isDone) ;,结论与上面相同。

上一篇 下一篇

猜你喜欢

热点阅读