作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个协程如下:
IEnumerator CountingCoroutine()
{
while (true)
{
DoSomething();
yield return new WaitForSeconds(1);
}
}
我需要在其中调用一些异步函数。如果我这样写,编译器会报错:
async IEnumerator CountingCoroutine()
{
while (true)
{
DoSomething();
await foo();
yield return new WaitForSeconds(1);
}
}
每秒调用一些异步函数的正确等待时间是多少?附言我可以放弃整个协程功能并使用具有计时机制的更新,并将更新功能标记为异步。但我不确定它是否安全或是否值得推荐。
@derHugo 推荐的解决方案:
IEnumerator CountingCoroutine()
{
while (true)
{
DoSomething();
var task = Task.Run(foo);
yield return new WaitUntil(()=> task.IsCompleted);
yield return new WaitForSeconds(1);
}
}
最佳答案
您可以使用 Task.IsCompleted
喜欢
private IEnumerator CountingCoroutine()
{
while (true)
{
DoSomething();
var task = Task.Run(foo);
yield return new WaitUntil(()=> task.IsCompleted);
}
}
它会在前一个任务完成后立即开始运行新任务。
您可以扩展它以便最早大约每秒开始一个新任务,或者在前一个任务在一秒后完成时最晚开始,例如
private IEnumerator CountingCoroutine()
{
var stopWatch = new StopWatch();
while (true)
{
DoSomething();
stopWatch.Restart();
var task = Task.Run(foo);
yield return new WaitUntil(()=> task.IsCompleted);
var delay = Mathf.Max(0, 1 - stopWatch.ElapsedMilliseconds * 1000);
// Delays between 1 frame and 1 second .. but only the rest that foo didn't eat up
yield return new WaitForSeconds(delay);
// or you could with a bit more calculation effort also
// even avoid the one skipped frame completely
if(!Mathf.Approximately(0, delay)) yield return new WaitForSeconds(delay);
}
}
或者如果你不关心完成,只想按你所说的那样调用它,那么就简单地做
private IEnumerator CountingCoroutine()
{
while (true)
{
DoSomething();
Task.Run(foo);
yield return new WaitForSeconds(1);
}
}
但是请注意,这样您将失去所有控制权,并且永远不会知道其中一项任务是否以及何时完成,并且可能会导致多个并发任务运行/失败等
作为替代方案,您也可以反过来使用 Asyncoroutine 之类的东西) .. 不过,您可能需要注意落在后台线程上的东西。
关于unity3d - 如何在 Unity 的协程函数中使用 await 调用异步函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64311768/
我是一名优秀的程序员,十分优秀!