起因
最近在油管上看到了一个关于Async 和 Coroutines的对比,刚好中间有一个例子,使用Async解决双指同时点击两个不同的Button,会触发两段逻辑的Bug,而且整段代码写起来非常快乐
优缺点对比
返回值功能对比
同步功能对比
try catch 功能对比
调用堆栈功能对比
Exception 隐藏功能对比
exit 功能对比
生命周期对比
Coroutine 的生命周期取决于MonoBehavior
Async 的声明周期需要手动控制
所以引出了Cancel Task的逻辑
需要注意的是在还没有执行到Cancel的时候,这个GameObject 被销毁了,这个时候依然无法取消
PopUp Window 例子
效果展示
这里没有做窗口,只是单纯展示逻辑
- 点击Test 开启监听,之后点击Accept返回True,点击Cancel或X,返回False
- 点击Test 开启监听,之后点击CancelTest,取消刚刚的Task
- 无论执行结果是什么,或者取消,都会输出Finally
视频中的例子还包含返回的Button,这里的例子就不包含这个部分了
UI Async 代码
利用Async 可以天然解决掉双指触摸Button的Bug,之前需要写一堆控制,非常不快乐
下面的代码用来举例说明具体调用,在项目中还需要另外调整
public class AsyncTest : MonoBehaviour {
public Button ButtonAccept;
public Button ButtonCancel;
public Button ButtonClose;
private CancellationTokenSource cts;
public async Task<bool> Spawn(CancellationToken ct) {
using(var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(ct)){
try{
CancellationToken linkedCt = linkedCts.Token;
var buttonTask = Utils.SelectButton(linkedCt, ButtonAccept, ButtonCancel, ButtonClose);
await buttonTask;
linkedCts.Cancel();
return buttonTask.Result == ButtonAccept;
}
catch(OperationCanceledException e){
Debug.Log("Cancel Operation");
return false;
}
finally{
linkedCts.Dispose();
Debug.Log("Finally");
}
}
}
public async void TestButton() {
cts = new CancellationTokenSource();
bool result = await Spawn(cts.Token);
Debug.Log(result);
}
public void CancelTestButton() {
cts.Cancel();
Debug.Log("Cancel");
}
}
public static class Utils {
public static async Task<Button> SelectButton(CancellationToken ct, Button accept, Button cancel, Button close) {
bool isSelect = false;
Button selectedBtn = null;
accept.onClick.AddListener(
() => {
isSelect = true;
selectedBtn = accept;
}
);
cancel.onClick.AddListener(
() => {
isSelect = true;
selectedBtn = cancel;
}
);
close.onClick.AddListener(
() => {
isSelect = true;
selectedBtn = close;
}
);
return await Task.Run(
() => {
while(true){
if(ct.IsCancellationRequested) ct.ThrowIfCancellationRequested();
if(isSelect) return selectedBtn;
}
},
ct
);
}
}
写的很仔细,对我帮助很大。而且页面布局美观,排版用心。感谢!~
有帮助就好~