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<T>
接口实际上做了什么。
IEnumerable<T>
是完全无状态的;它只是公开了一个 GetEnumerator()
方法,该方法将有状态的枚举器交还给他们,以跟踪它们的进度。
您需要在两个循环之间传递相同的 enumerator 实例。 foreach
只能在 IEnumerable<T>
(或类似的)上运行,因此您需要将它们替换为直接使用 IEnumerator<T>
的 while
循环。
确保在所有代码路径中处理 IEnumerator
(否则,finally
或 using
块将不会运行)。
【讨论】:
以上是关于C# yield return 枚举器,从部分继续的主要内容,如果未能解决你的问题,请参考以下文章