是否可以使用Async CTP来模拟延续和尾递归?
我正在考虑以下几点:
async Task Loop(int count)
{
if (count == 0)
retrun;
await ClearCallStack();
//is it possible to continue here with a clean call stack?
Loop(count -1)
}
我想我们需要一个自定义调度程序等,但它可能吗? (也就是说,它可以用于递归而无需吹掉调用堆栈)
答案 0 :(得分:4)
是的,这完全有可能。
在最新的Async CTP(Refresh for VS2010 SP1)中,单元测试示例中有一个“GeneralThreadAffineContext”类(在VB或C#中)。这提供了必要的帮助程序代码,用于以通用线程仿射方式运行异步方法。
通过线程亲和性,我们的意思是异步连续在与原始线程相同的上下文中处理,类似于WinForms / WPF的行为,但没有启动真正的WPF或WinForms消息循环。
Task.Yield()
的设计是将当前方法的其余部分推迟到SynchronizationContext,因此您甚至不需要编写自己的await ClearCallStack()
。相反,您的样本将归结为:
async Task DoLoop(int count)
{
// yield first if you want to ensure your entire body is in a continuation
// Final method will be off of Task, but you need to use TaskEx for the CTP
await TaskEx.Yield();
if (count == 0)
return;
//is it possible to continue here with a clean call stack?
DoLoop(count -1)
}
void Loop(int count)
{
// This is a stub helper to make DoLoop appear synchronous. Even though
// DoLoop is expressed recursively, no two frames of DoLoop will execute
// their bodies simultaneously
GeneralThreadAffineContext.Run(async () => { return DoLoop(count); });
}