在递归方法中使用async/await的正确方法是什么?

Pra*_*bhu 6 .net c# recursion asynchronous async-await

在递归方法中使用async/await的正确方法是什么?这是我的方法:

public string ProcessStream(string streamPosition)
{
    var stream = GetStream(streamPosition);

    if (stream.Items.count == 0)
        return stream.NextPosition;

    foreach(var item in stream.Items) {
        ProcessItem(item);
    }

    return ProcessStream(stream.NextPosition)
}
Run Code Online (Sandbox Code Playgroud)

这是使用async/await的方法:

public async Task<string> ProcessStream(stringstreamPosition)
{
        var stream = GetStream(streamPosition);

        if (stream.Items.count == 0)
            return stream.NextPosition;

        foreach(var item in stream.Items) {
            await ProcessItem(item); //ProcessItem() is now an async method
        }

        return await ProcessStream(stream.NextPosition);
 }
Run Code Online (Sandbox Code Playgroud)

Kir*_*kiy 7

虽然我必须提前说这个方法的意图对我来说并不完全清楚,但用一个简单的循环重新实现它是非常简单的:

public async Task<string> ProcessStream(string streamPosition)
{
    while (true)
    {
        var stream = GetStream(streamPosition);

        if (stream.Items.Count == 0)
            return stream.NextPosition;

        foreach (var item in stream.Items)
        {
            await ProcessItem(item); //ProcessItem() is now an async method
        }

        streamPosition = stream.NextPosition;
    }
}
Run Code Online (Sandbox Code Playgroud)

递归不是堆栈友好的,如果您可以选择使用循环,那么在简单的同步场景(控制不良的递归最终会导致StackOverflowExceptions)以及异步场景中,它绝对值得研究,其中,我将是说实话,我甚至不知道如果你把事情推得太远会发生什么(每当我试图用async方法重现已知的堆栈溢出场景时,我的VS测试资源管理器崩溃).

诸如Recursion和await/async关键字之类的答案表明,由于状态机的工作方式,这不是StackOverflowException一个问题,但这不是我已经探索过的东西,因为我倾向于尽可能避免递归.asyncasync/await