什么是使用异步/等待一个递归方法正确的方法是什么? [英] What is the correct way to use async/await in a recursive method?

查看:250
本文介绍了什么是使用异步/等待一个递归方法正确的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是使用异步/伺机在递归方法正确的方法是什么?下面是我的方法:

 公共字符串ProcessStream(字符串streamPosition)
{
    VAR流= GetStream(streamPosition);

    如果(stream.Items.count == 0)
        返回stream.NextPosition;

    的foreach(在stream.Items VAR项){
        ProcessItem(项目);
    }

    返回ProcessStream(stream.NextPosition)
}
 

这里是方法异步/等待:

 公共异步任务<字符串> ProcessStream(stringstreamPosition)
{
        VAR流= GetStream(streamPosition);

        如果(stream.Items.count == 0)
            返回stream.NextPosition;

        的foreach(在stream.Items VAR项){
            等待ProcessItem(项目); // ProcessItem()现在是一个异步方法
        }

        返回等待ProcessStream(stream.NextPosition);
 }
 

解决方案

虽然我不得不说的前期,该方法的意图并不完全清楚,我,用一个简单的循环重新实现它是相当简单:

 公共异步任务<字符串> ProcessStream(字符串streamPosition)
{
    而(真)
    {
        VAR流= GetStream(streamPosition);

        如果(stream.Items.Count == 0)
            返回stream.NextPosition;

        的foreach(在stream.Items VAR项)
        {
            等待ProcessItem(项目); // ProcessItem()现在是一个异步方法
        }

        streamPosition = stream.NextPosition;
    }
}
 

递归是不能叠加友好的,如果你有使用循环的选择,它的东西绝对值得期待成简单的同步方案(其中,不良的最终控制递归导致 StackOverflowException S),以及异步场景,在这里,我会说实话,我甚至不知道,如果你把东西太远会发生什么(我的VS测试资源管理器崩溃每当我试图重现称为堆栈溢出情景异步方法)。

像这样的回答递归和表明计谋/异步关键字 StackOverflowException 少的问题与异步由于路异步/计谋状态机的工作原理,但是这不是我已经探索了很多,因为我倾向于尽可能避免递归。

What is the correct way to use async/await in a recursive method? Here is my method:

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

And here is the method with 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);
 }

解决方案

While I have to say upfront that the intention of the method is not entirely clear to me, reimplementing it with a simple loop is quite trivial:

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

Recursion is not stack-friendly and if you have the option of using a loop, it's something definitely worth looking into in simple synchronous scenarios (where poorly controlled recursion eventually leads to StackOverflowExceptions), as well as asynchronous scenarios, where, I'll be honest, I don't even know what would happen if you push things too far (my VS Test Explorer crashes whenever I try to reproduce known stack overflow scenarios with async methods).

Answers such as Recursion and the await / async Keywords suggest that StackOverflowException is less of a problem with async due to the way the async/await state machine works, but this is not something I have explored much as I tend to avoid recursion whenever possible.

这篇关于什么是使用异步/等待一个递归方法正确的方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆