百科问答小站 logo
百科问答小站 font logo



使用yield可以做哪些很酷的事情? 第1页

  

user avatar   Ivony 网友的相关建议: 
      

最典型的不就是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就成功了。




  

相关话题

  数学/算法:正方形内有5个点,为什么最近点对的距离小于边长? 
  c++如此繁琐,为什么大学不直接开展python课程? 
  就节省编译时间来说,Precompiled Header和Pimpl范式哪个更好? 
  内存为啥要分堆栈在编程里,要是全部只用堆或者全部只用栈,行不行? 
  C语言开发单片机为什么大多数都采用全局变量的形式? 
  游戏开发在向去编程化发展吗? 
  用c#开发桌面应用,如何做出漂亮的界面? 
  使用基于LGPL授权QT的『歪歪yy语音』允许反编译吗? 
  Python 中有什么不容易让人察觉的有趣的事实? 
  新手该如何使用 GitHub? 

前一个讨论
用能源作为虚拟货币的背书,那么这种货币能不能成为虚拟货币?
下一个讨论
100个金币,只有1个略重,其余99个一样重。给你一个天平,最少称几次能确保找出那个略重的?





© 2025-04-24 - tinynew.org. All Rights Reserved.
© 2025-04-24 - tinynew.org. 保留所有权利