1

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)
}

カスタムスケジューラなどが必要だと思いますが、可能でしょうか?(つまり、コールスタックを吹き飛ばさずに再帰するために使用できます)

4

1 に答える 1

4

はい、これは完全に可能です。

最新の 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); });
}
于 2011-04-14T20:11:55.540 に答える