UniTask
# UniTask
# 什么是UniTask
UniTask是基于C# 5的async和await异步定制的一套Unity优化的异步解决方案;需要Unity2017以上的版本,并且需要升级c#库, 但并不如UniRx项目提供的更为轻量级,可是UniTask拥有强大的async/await和unity进行交互。
# 一般什么情况下使用UniTask
一般来说首先想到的是网络相关的处理和资源加载需要用UniTask来处理,使用UniRx来处理感觉不够用;还有复杂的运算也可以使用UniTask,当作一个线程来使用就好。
# 基于Unity AsyncOperation拓展的async&awaitAPI
所有Unity中的异步AsyncOperation都可以使用await来等待异步结果,包括AsyncLoadScene、AsyncLoadAsset、AsyncOperation
public class No22_UniTask : MonoBehaviour
{
async void StartAsync()
{
// 加载资源
var load = await Resources.LoadAsync<TextAsset>("1");
// 加载场景
await SceneManager.LoadSceneAsync("SampleScene")
.ConfigureAwait(Progress.Create<float>(p => Debug.LogFormat("p:{0}", p)));
// 网络请求
UnityWebRequest req = UnityWebRequest.Get("http://www.baidu.com");
var op = await req.SendWebRequest();
}
void Start()
{
StartAsync();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# UniTask API
UniTask.WaitUntil
UniTask.WaitWhile
UniTask.WaitUntilValueChanged
UniTask.SwitchToThreadPool
UniTask.SwitchToTaskPool
UniTask.SwitchToMainThread
UniTask.SwitchToSynchronizationContext
UniTask.Yield
UniTask.Run
UniTask.Lazy
UniTask.Void
UniTask.ConfigureAwait
UniTask.DelayFrame
UniTask.Delay(…, bool ignoreTimeScale = false, …) parameter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# UniTask.WaitUntil
一直等待直到达到某种条件,才执行下面的代码
public class No22_UniTask : MonoBehaviour
{
private bool mValue;
async void StartAsync()
{
Debug.LogFormat("frame start:{0}", Time.frameCount);
Observable.TimerFrame(100).Subscribe(_ => mValue = true);
// 一直等待直到达到某种条件,才执行下面的代码
await UniTask.WaitUntil(() => mValue == true);
Debug.LogFormat("frame end:{0}", Time.frameCount);
}
void Start()
{
StartAsync();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# UniTask.WaitWhile
当达到某种条件才进行等待,条件失败通过
public class No22_UniTask : MonoBehaviour
{
private bool mValue;
async void StartAsync()
{
Debug.LogFormat("frame start:{0}", Time.frameCount);
Observable.TimerFrame(100).Subscribe(_ => mValue = true);
// 当达到某种条件才进行等待,条件失败通过
await UniTask.WaitWhile(() => mValue == false);
Debug.LogFormat("frame end:{0}", Time.frameCount);
}
void Start()
{
StartAsync();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# UniTask.WaitUntilValueChanged
一直等待直到值有变化了之后才之执行后面的代码
# UniTask.SwitchToThreadPool
之后的代码运行在线程池中
public class No22_UniTask : MonoBehaviour
{
private bool mValue;
async void StartAsync()
{
Debug.LogFormat("frame start:{0}", Time.frameCount);
Observable.TimerFrame(100).Subscribe(_ => mValue = true);
//之后的代码运行中线程池中
await UniTask.SwitchToThreadPool();
// 当达到某种条件才进行等待,条件失败通过
await UniTask.WaitWhile(() => mValue == false);
Debug.LogFormat("frame end:{0}", Time.frameCount);
}
void Start()
{
StartAsync();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# UniTask.SwitchToTaskPool
之后的代码运行在任务池中
# UniTask.SwitchToMainThread
*之后的代码运行在主线程中
# UniTask.SwitchToSynchronizationContext
之后的代码运行在同步句柄中
# UniTask.Yield
相当于yiled return [operation]
public class No22_UniTask : MonoBehaviour
{
async void StartAsync()
{
Debug.LogFormat("frame start:{0}", Time.frameCount);
// PlayerLoopTiming.PostLateUpdate = WaitForEndOfFrame
// yield return null
// yield return WaitForFixedUpdate
await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
Debug.LogFormat("frame end:{0}", Time.frameCount);
}
void Start()
{
StartAsync();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# UniTask.Run
启动一个标准的线程
public class No22_UniTask : MonoBehaviour
{
async void StartAsync()
{
Debug.LogFormat("frame start:{0}", Time.frameCount);
// 启动一个标准的线程
await UniTask.Run(() => Debug.Log("heavy task heavy cal"));
Debug.LogFormat("frame end:{0}", Time.frameCount);
}
void Start()
{
StartAsync();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# UniTask.Lazy
启动一个回调线程
public class No22_UniTask : MonoBehaviour
{
private UniTask<int> mLazy;
async void StartAsync()
{
Debug.LogFormat("frame start:{0}", Time.frameCount);
// 启动一个回调线程
await UniTask.Lazy<int>(() => UniTask.DelayFrame(100));
Debug.LogFormat("frame end:{0}", Time.frameCount);
}
void Start()
{
StartAsync();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# UniTask.Void
void回调辅助方法
public class No22_UniTask : MonoBehaviour
{
async void StartAsync()
{
Debug.LogFormat("frame start:{0}", Time.frameCount);
// void回调辅助方法
UniTask.Void(Method);
Debug.LogFormat("frame end:{0}", Time.frameCount);
}
private UniTask Method()
{
return UniTask.DelayFrame(100);
}
void Start()
{
StartAsync();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# UniTask.ConfigureAwait
基于AsyncOperation的拓展配置
public class No22_UniTask : MonoBehaviour
{
async void StartAsync()
{
Debug.LogFormat("frame start:{0}", Time.frameCount);
// 基于AsyncOperation的拓展配置
Resources.LoadAsync<TextAsset>("1").ConfigureAwait(Progress.Create<float>(p => Debug.LogFormat("p:{0}", p)));
Debug.LogFormat("frame end:{0}", Time.frameCount);
}
private UniTask Method()
{
return UniTask.DelayFrame(100);
}
void Start()
{
StartAsync();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# UniTask.DelayFrame
延时指定的帧数执行下面的代码
# UniTask.Delay(…, bool ignoreTimeScale = false, …) parameter
延时指定的时间执行下面的代码
# UniTaskTracker 可视化任务
使用UniTask的监视器,可以监视当前执行的哪些任务
# 其他设置
Enable AutoReload:是否允许自动加载task
Enable Tracking: 是否允许跟踪task
Enable StackTrace:是否允许堆栈跟踪
Reload:重新加载task列表
GC.Collect:进行GC回收
1
2
3
4
5
2
3
4
5
上次更新: 2023/10/17, 14:09:52 访问次数: 0