异步方法不识别yield return方法?

3

问题

当我尝试在异步方法中调用我的“普通”方法时,调试器会忽略它1

这是我的异步方法:

[原始回答]

 internal async static Task<DefinitionsModel> DeserializeAsync(this string path)
 {
        var model = new DefinitionsModel();
        var content = await File.ReadAllTextAsync(path);

        model.Pages = content.GetPages();

        return model;
 }

最初的回答是:

这里是我的“常规”方法


private static IEnumerable<PageModel> GetPages(this string content)
{            
        var level = 0;
        var value = nameof(PageModel.Page).GetDElement<PageModel>();
        var start_with_line = $"{level} {value} ";
        var end_with_line = string.Concat(Enumerable.Repeat(Environment.NewLine, 2));

        var expression = $@"\b{start_with_line}\S * {end_with_line}\b";
        var matches = content.GetPagesFromContent(expression);


        yield return new PageModel();
}

HELPER PICTURES

image link


这可能是因为您的 IEnumerable<T> 结果未被迭代/持久化。例如,当在 foreach 循环中使用该方法时,它才会被执行。 - Jeroen van Langen
2
@phuzi 我的问题不是关于List vs IEnumeable... - Zer0
1
一个只有单个 yield 语句的方法确实很奇怪,为什么不直接返回一个单个的 PageModel - DavidG
我同意标题有误导性,但那里的解释实际上非常有用。@OverZer0 - Patrick Hofman
@DavidG 我还没有完成我的方法,我只是想看一下“匹配集合”有什么值。 - Zer0
2个回答

7

yield只有在被枚举时才会产生结果。在这种情况下:

model.Pages = content.GetPages();

这里没有枚举。但是你可以这样做:

model.Pages = content.GetPages().ToList();

你可以使用foreach语句或LINQ查询来消耗迭代器方法,而不出所料,ToList()使用foreach来迭代IEnumerable
虽然老实说,我很难弄清楚你在做什么,很可能需要重新考虑GetPagesyield (C# 参考) 当您在语句中使用yield关键字时,表示出现该关键字的方法、运算符或get访问器是一个迭代器。使用yield定义迭代器可以避免在实现自定义集合类型的IEnumerable和IEnumerator模式时需要显式额外类(保存枚举状态的类,请参见IEnumerator)。使用yield return语句逐个返回每个元素。通过使用foreach语句或LINQ查询来使用迭代器方法。foreach循环的每次迭代都调用迭代器方法。当迭代器方法到达yield return语句时,表达式被返回,并保留当前代码位置。下一次调用迭代器函数时从该位置重新启动执行。

1
你的GetPages方法返回一个带有yield returnIEnumerable<T>。编译器会从该代码构建状态机。
只有在使用生成的状态机中的GetEnumerator()方法获取枚举器并进行迭代时,该代码才会被执行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接