C# yield return 枚举器,从部分继续

Posted

技术标签:

【中文标题】C# yield return 枚举器,从部分继续【英文标题】:C# yield return enumerator, continue from part the way through 【发布时间】:2018-05-18 05:07:54 【问题描述】:

我正在使用 yield return 来处理一些数据,其中包含一组不确定的迭代。我想开始处理,但是一旦遇到条件(例如字节大小)就从循环中中断,将枚举器传递给将继续处理的新线程,然后返回到目前为止处理的结果。

实际上,我有一个 foreach 循环,我可能会在结束前跳出。如何将 IEnumerable 传递给新线程并从我离开的地方而不是开始处“继续”?

public static IEnumerable<String> Process()

    // static values added for simplicity, but will be a variable number of returns
    yield return "1";
    yield return "2";
    yield return "3";
    yield return "4";
    yield return "5";
    yield return "6";    


List<String> main()

    List<String> retVal = new List<String>();
    IEnumerable<String> strList = Process();

    foreach(String strItem in strList)
    
        retVal.Add(strItem);
        Console.WriteLine(strItem);
        // Time to send something back and continue in a new thread
        if (strItem.Equals("3"))
        
            break;
        
            

    new Thread(() => ThreadFunc(strList)).Start();
    return retVal;


public static void ThreadFunc(IEnumerable<String> strList)

    List<String> retVal = new List<String>();
    foreach(String strItem in strList)
     
        retVal.Add(strItem);
        Console.WriteLine(strItem);
       
     // Send the rest of the data


所需输出:1 2 3 4 5 6

实际输出:1 2 3 1 2 3 4 5 6

谢谢。

【问题讨论】:

您需要一些更复杂的东西(一种跟踪当前位置的类型)或将要跳过的项目数传递给在另一个线程中运行的代码。 @juharr:不;你只需要一个枚举器。 @SLaks 或者那样,但你必须小心确保正确处理它。 @juharr 如果您要多次迭代序列,则会有很多问题。您正在重新计算序列的大部分生成,并且您假设序列的内容在每次迭代时都是相同的,而且它甚至 可能多次迭代它,通常情况并非如此。必须记住处理枚举器只是实际获得正确结果所需要的。 【参考方案1】:

看看IEnumerable&lt;T&gt;接口实际上做了什么。

IEnumerable&lt;T&gt; 是完全无状态的;它只是公开了一个 GetEnumerator() 方法,该方法将有状态的枚举器交还给他们,以跟踪它们的进度。

您需要在两个循环之间传递相同的 enumerator 实例。 foreach 只能在 IEnumerable&lt;T&gt;(或类似的)上运行,因此您需要将它们替换为直接使用 IEnumerator&lt;T&gt;while 循环。

确保在所有代码路径中处理 IEnumerator(否则,finallyusing 块将不会运行)。

【讨论】:

以上是关于C# yield return 枚举器,从部分继续的主要内容,如果未能解决你的问题,请参考以下文章

C#中yield用法

C#中的yield return与Unity中的Coroutine(协程)

yield return关键字怎么使用?

yield(C# 参考)

c#我们为什么要用 yield return

python中yield与return的用法与区别