The 其他答案 https://stackoverflow.com/a/70358869/7111561很好,但实际上并不适合您要解决的用例。
您没有任何异步代码,但需要在 Unity 主线程中执行代码,因为它使用 Unity API 并且大部分代码只能在主线程上使用。
A 协程 https://docs.unity3d.com/Manual/Coroutines.html is 非异步与多线程或任务无关!
协程基本上只是一个IEnumerator
一旦它被注册为协程StartCorotuine
然后Unity调用MoveNext
在它上面(这将执行一切,直到下一个yield return
声明)之后Update
所以一旦一帧(有一些特殊的yield语句,比如WaitForFixedUpdate
等,它们在不同的消息堆栈中处理,但仍然在 Unity 主线程上处理。
So e.g.
// Tells Unity to "pause" the routine here, render this frame
// and continue from here in the next frame
yield return null;
or
// Will once a frame check if the provided time in seconds has already exceeded
// if so continues in the next frame, if not checks again in the next frame
yield return new WaitForSeconds(3f);
如果您确实需要以某种方式对例程本身内的取消做出反应,那么除了立即抛出异常而不是仅检查CancellationToken.IsCancellationRequested https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.iscancellationrequested#System_Threading_CancellationToken_IsCancellationRequested并对其做出反应
while (time < duration)
{
if(token.IsCancellationRequested)
{
// Handle the cancelation
// exits the Coroutine / IEnumerator regardless of how deep it is nested in loops
// not to confuse with only "break" which would only exit the while loop
yield break;
}
....
也回答你的标题。确实你做不到yield return
里面一个try - catch
阻止并且正如一般所说,无论如何都没有真正的理由这样做。
如果您确实需要,您可以包装代码的某些部分,而无需yield return
in a try - catch
块并在catch
你做了你的错误处理,然后你就可以再次yield break
.
private IEnumerator SomeRoutine()
{
while(true)
{
try
{
if(Random.Range(0, 10) == 9) throw new Exception ("Plop!");
}
catch(Exception e)
{
Debug.LogException(e);
yield break;
}
yield return null;
}
}