对迭代方法进行"迭代"

Jas*_*ban 2 duck-typing pattern-matching c#-5.0 async-ctp

关于异步CTP的一些相关问题:

  • 我可以使用然后使用枚举器方法迭代Iterator Block(IEnumerable<T>返回yield T),以及.方法的模拟是什么?一个非调用方法如何接收和处理任何ed项然后呢?你能提供一个简短的例子吗?我只是没有看到它.GetEnumerator()MoveNext()Current()asyncasyncawaitContinueWith()

  • 此外,在下面的示例async方法中,MyAwaitable有一个GetAwaiter()方法.如果GetAwaiter()返回stringTHuh不是string,编译器不会抱怨.THuh和之间存在什么类型的约束/期望GetAwaiter()

    async Task<THuh> DoSomething()
    {
         var x = await new MyAwaitable("Foo");
    
         var y = await new MyAwaitable("Bar");
    
         return null;
    } 
    
    Run Code Online (Sandbox Code Playgroud)
  • 请解释C#规范草案的以下行.是否async Task<T>应该方法returndefault(T),将永远不会被使用?我看到一些似乎不符合此规则的示例 - 返回值似乎可以访问,值是非默认值.这个值无法访问吗?如果是这样,为什么尴尬难以接近的退货声明呢?

在具有Task<T>某些返回类型的异步函数中T,return语句必须具有可隐式转换为的表达式T,并且必须无法访问正文的端点.

  • 规范说"所有GetAwaiter,IsCompleted,OnCompleted和GetResult都是"非阻塞的" - 那么在什么方法中应该定义(可能)长时间运行的操作?

谢谢!

Eri*_*ert 7

我正在尝试使用Iterator Blocks转换继续传递(非常但很成功)并将其转换为使用异步.我想我正在以新的方式战斗.了解这种变化感觉就像拆开3英寸宽的魔术贴条.

我能理解你是怎么想的那样.我不鼓励人们试图用迭代器块来构建CPS,因为无论迭代器和CPS的共同基础机制是什么,它都不适合.迭代器块旨在为快速制作将数据结构转换为序列或将序列转换为不同序列的方法感觉良好; 它们的目的不是解决电流持续呼叫的一般问题.

就此而言,async/await也不是精确地用电流继续调用,尽管它显然更接近一个数量级.Async/await旨在使基于任务的异步更容易; 它通过将代码重写为延续传递样式的形式来实现,这是一个实现细节.

我在相关主题上写的这个答案可能有所帮助:

如何使用call/cc实现c#5.0中的新异步功能?

我怀疑你所遇到的概念性问题是在迭代器风格的异步中,"orchestrator" - 当迭代器块从中断时恢复的东西 - 是你的代码.你编写了一些代码,然后决定何时调用MoveNext来抽取迭代器.使用基于任务的异步,其他一些代码可以为您完成.当任务完成时,将该事实发布到某处的消息队列的几率很好,然后当泵出消息队列时,继续将被激活并返回结果.您可以指出代码中没有明确的"MoveNext"; 相反,任务已完成并知道其自身的延续这一事实足以确保将继续放在工作队列中以便最终执行.

如果您有更多问题,我建议您将其发布在SO和/或异步论坛上.