C#yield return enumerator,从部分继续进行

时间:2017-12-04 17:02:25

标签: c# iterator yield enumerable enumerator

我使用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

谢谢。

1 个答案:

答案 0 :(得分:4)

查看IEnumerable<T>界面实际执行的操作。

IEnumerable<T>完全无国籍;它只是暴露了一个GetEnumerator()方法,该方法可以提供有状态的枚举器,以跟踪它们的位置。

您需要在两个循环之间传递相同的enumer ator 实例。 foreach只能在IEnumerable<T>(或类似)上运行,因此您需要将其替换为直接使用while的{​​{1}}循环。

确保在所有代码路径中都放置IEnumerator<T>(否则,IEnumeratorfinally块将无法运行。