Unity中的异步编程【1】——Unity与async、await
新⼿在Unity⾥写东西,⼀个⽅法的内容如果写复杂了,容易把Uinty写死,就会卡帧,⽤流⾏的话来总结就是:在Update⾥⾯活⽣⽣把天聊死了。
此外,如果新⼿才⼊门,不擅长使⽤消息、事件来进⾏异步的统筹,⼀门⼼思在Update⾥⾯实现各种有延时有顺序的步骤,于是⾃⼰把⾃⼰绕晕不说,程序⼜难调试,难修改,更甚——帧率低下…
那么⽤协程来实现异步…聪明…
但,还有⽐协程更好⽤的异步框架,那就是UniTask
⼀、什么是异步:async和await是啥
异步这个概念⼀⾔难尽,⾥⾯涉及到很多上古时候的知识:单核/多核,单线程/多线程,并发/并⾏,阻塞/⾮阻塞…
举⼀个例⼦:
⼩赵夫妻响应祖国的号召,夫妻⼆⼈7年之内哗啦啦⽣了3个娃娃。对这对夫妻来说,他们⽣娃只能⼀胎⼀胎的⽣,所以⼩赵家⽣三娃这件事情就是单线程,⽽且是阻塞式的。
await和async使用方法⼜过了⼏年,⼈们纷纷进城,村⾥的⼈越来越少,于是⼤家响应号召要多多⽣娃,特别是赵庄的赵太爷在县太爷⾯前拍了胸脯:2年之内,我们赵庄要增加100个新⽣⼉。
于是赵太爷在村⾥做了动员,⼤伙⼉也积极响应,纷纷备孕。于是赵庄⽣100个娃这件事情变成了多线程,⽽且是⾮阻塞的(⼤家⼀起⽣——这叫多线程,张家怀孕不会影响李家怀孕——这叫⾮阻塞)。
⼆、C#(.Net)中的异步
.Net⾃C#5开始,⼤概2012年前后,开始引⼊了异步编程(async和await),有了异步之后,很少需要⼿动去开线程了,⽽且业务更好理解,代码更加清晰。
同步举例:解放前的⾟家庄有⼗户⼈,他们共⽤⼀个灶做饭,于是只能轮着顺序做饭…
以上做饭的总耗时为10代码清单
using;
using;//关键的包
public static void Cooking(int i ){
Console.WriteLine($"第{i}户家庭开始做饭...");
Task.Delay(1000).Wait();
Console.WriteLine($"第{i}户家庭做饭结束");
}
public static void TestCooking(){
for(int i =0;i<10;i++)
{
Cooking(i);
}
}
TestCooking();
异步举例:现在他们富裕了,每家都有⼀个灶,于是做饭的时候全村炊烟袅袅,⼤家各做各的,这做饭就成了并发(并⾏)。
张家做饭和李家做饭和不⼲涉,互不阻碍。
以下是他们⼗家⼀起做饭的壮观情景:
请注意红框中的【async】和【await】关键字
各家在各家做饭,虽然同⼀时间开始做,但总耗时为1代码清单
public static async Task Cooking(int i ){
Console.WriteLine($"第{i}户家庭开始做饭...");
await Task.Delay(1000);
Console.WriteLine($"第{i}户家庭做饭结束");
}
public static async Task TestCooking(){
var allTasks =new List<Task>();
for(int i =0;i<10;i++)
{
allTasks.Add(Cooking(i));
}
await Task.WhenAll(allTasks.ToArray());
}
await TestCooking();
三、 Unity中的异步
问题的提出:点了按钮,隔三秒启动发动机,发动机转4秒,然后停机。以上内容把它写在⼀个⽅法⾥⾯。
解决办法1:⼀般⼤家能够想到的就是协程,没问题,这是Unity标准玩法,但是协程没有返回值,也不能好好调试…
解决办法2:聪明的你肯定想到.NET的 async和await了,但是,不好意思,Unity不能完美⽀持,⽐如在WebGL⾥⾯,就不⽀持多线程,async和await背后是多线程。所以,此路不通。
解决办法3:UniRX和UniTask
UniRX是上世代的产物,响应式编程兴起的时候创建的项⽬,⾄今已经进⼊稳态,官⽹特别说明,如果你要搞异步编程,那么就⽤UniTask,因为异步功能已经从UniRX拆分到UniTask了。
⽤UniTask完成以上业务:
点击【Button】后,启动发动机…停⽌发动机:
代码清单:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论