【发布时间】:2021-06-08 06:21:25
【问题描述】:
我正在尝试编写一个递归方法来检索对象的父对象(以及该父对象等)。这本身不是问题,但调用是异步的,这会导致以下错误:
'.....Recursive(string)' 的主体不能是迭代器块,因为'Task
' 不是迭代器接口类型 [...]csharp(CS1624)
代码:
private async Task<IEnumerable<string>> Recursive(string objectId)
{
var result = await GetParent(objectId);
if (result?.Length > 0)
{
yield return result;
await Recursive(objectId);
}
}
private async Task<string> GetParent(string objectId)
{
await Task.Run(() => { return $"{objectId}/parent"; });
}
我也尝试过IAsyncEnumerable,但这导致了以下错误:
“IAsyncEnumerable”不包含“GetAwaiter”的定义,并且找不到接受“IAsyncEnumerable”类型的第一个参数的可访问扩展方法“GetAwaiter”(您是否缺少 using 指令或程序集引用?)[。 ..]csharp(CS1061)
private async IAsyncEnumerable<string> Recursive(string objectId)
{
var result = await GetParent(objectId);
if (result?.Length > 0)
{
yield return result;
await Recursive(objectId);
}
}
private async Task<string> GetParent(string objectId)
{
await Task.Run(() => { return $"{objectId}/parent"; });
}
我要写一个while循环来让它工作。但我对这是否可能很感兴趣。
更新 2: 好的,我想我明白了。谢谢大家。
private async IAsyncEnumerable<string> Recursive(string objectId)
{
var result = await GetParent(objectId);
if (result?.Length > 0)
{
yield return result;
await foreach (var r2 in Recursive(objectId))
{
yield return r2;
}
}
}
private async Task<string> GetParent(string objectId)
{
await Task.Run(() => { return $"{objectId}/parent"; });
}
【问题讨论】:
-
Task<IEnumerable<string>>类型承诺消费者可能需要等待一段时间,但是一旦等待结束,消费者将能够毫不拖延地获取所有元素。您的方法没有这样做:在产生结果之后,可能会进一步延迟。您确实需要IAsyncEnumerable,它允许连续元素之间的延迟。但是,您没有向我们提供任何有关“导致更多问题”的信息,因此很难提供帮助 -
错误很明显——你不能使用
yield,除非方法返回IEnumerable或IAsyncEnumerable.这个实现不起作用。您对IAsyncEnumerable做了什么尝试? PS您写的内容也不适用于IEnumerable。您不能只从迭代器内部返回IEnumerable -
先尝试创建一个适用于
IEnumerable的递归方法,然后再将其转换为使用IAsyncEnumerable。 -
我不确定 async 是否相关,您不能按照您尝试的方式编写递归迭代函数,至少在我正确理解意图的情况下。迭代器块和递归不能很好地混合。如果可能的话,最好只编写一个迭代解决方案,或者为每个元素创建一个带有回调的递归解决方案。演示实际问题的示例可能会有所帮助。
-
一会儿,我将添加 IAsyncEnumerable 尝试..
标签: c# asynchronous recursion