【问题标题】:Continuations using Async CTP使用异步 CTP 继续
【发布时间】:2011-08-05 19:12:19
【问题描述】:

是否可以使用 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)
}

我想需要一个自定义调度程序之类的,但这可能吗? (也就是说,它是否可以用于递归而不破坏调用堆栈)

【问题讨论】:

    标签: continuations c#-5.0 async-ctp


    【解决方案1】:

    是的,这是完全可能的。

    在最新的 Async CTP(VS2010 SP1 的刷新)中,单元测试示例(在 VB 或 C# 中)中有一个“GeneralThreadAffineContext”类。这为仅以通用线程仿射方式运行异步方法提供了必要的帮助代码。

    线程关联性是指异步延续在与原始线程相同的上下文中处理,类似于 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); });
    }
    

    【讨论】:

    • 这些扩展在哪里?我已经安装了 SP1 异步刷新.. 找不到 yield 或 generalthreadaffinecontext
    • GeneralThreadAffineContext 不是官方 API 的一部分 - 它实际上是单元测试示例中的一些帮助代码。此外,出于 CTP 的目的,Yield() 是 TaskEx 的一种方法,因为我们的目标是让 CTP 框架 API 可部署,而无需修补 .NET 框架。
    猜你喜欢
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 2011-08-19
    • 2011-10-20
    相关资源
    最近更新 更多