最典型的不就是async/await么?
不了解yield怎么实现async/await的,用C#代码试举一例:
IEnumerable<Action<Action>> SomeAsyncMethod() { //blabla yield return await( asyncMethod, context ); //blabla yield return await( asyncMethod, context ); //blabla }
也就是说每次有异步调用的时候,把异步调用的方法包装成一个东西直接yield返回。
然后调用这个方法的时候用专用的异步处理器来调用。
void AsyncCall( IEnumerator<Action<Action>> asyncMethod ) { if ( asyncMethod.MoveNext() ) { var func = asyncMethod.Current; func( () => AsyncCall( asyncMethod ); } }
异步处理器也非常简单,不断地枚举asyncMethod序列里面返回的东西,然后把自己的调用包装成一个方法塞给这个东西。
最后就是这个所谓的东西,到底是什么?
其实很简单,这个东西是接受一个continuation的一个方法,执行一个异步操作,并在执行完成后调用continuation(也是一个方法)。
对于Task而言,其实这个方法可以用task.GetAwaiter().OnCompleted来得到。
一般的异步方法长成这样:
void BeginXXX( blabla, AsyncCallback callback )
我们把它先包装成这个样子,也就是把blabla的部分转换成一个参数
void AsyncMethod<T>( T context, Action callback )
然后这样转换一下:
public Action<Action> await<T>( Action<T, Action> asyncMethod, T context ) { return continuation => { asyncMethod( context, continuation ); }; }
至此,yield实现async/await就成功了。