前回のコルーチンっぽいものをC#で書いてみた。いろいろ問題があるかもしれないけど。
無限ループなので、Ctrl+Cかなんかで中断すべし。
/// <summary>The class which represent the co-routines which should be work cooperatively.</summary> /// <typeparam name="T">The type of return value of co-routines.</typeparam> class Coroutines<T> { /// <summary>The co-routines which should be work cooperatively.</summary> List<Func<IEnumerable<T>>> _routines; /// <summary>Constructor with routines.</summary> public Coroutines(params Func<IEnumerable<T>>[] tasks) { _routines = new List<Func<IEnumerable<T>>>(tasks); } /// <summary>Invoke each coroutine</summary> /// <param name="proc">The procedure which uses return value of the co-routine.</param> public void DoWork(Action<T> proc) { // prepare the iterators int nRoutines = _routines.Count; List<IEnumerator<T>> enums = new List<IEnumerator<T>>(); for (int i = 0; i < nRoutines; i++) enums.Add(_routines[i]().GetEnumerator()); // invoke each co-routine // each one is supposed to be invoked lazily but I am not sure about that... :-( for (; ; ) { for (int i = 0; i < nRoutines; i++) { enums[i].MoveNext(); T val = enums[i].Current; proc(val); } } } } /// <summary>The test program of co-routine.</summary> class Program { static void Main(string[] args) { // register co-routines Coroutines<string> tasks = new Coroutines<string>(Enumerate3, Enumerate5); // invoke tasks.DoWork(Console.WriteLine); } /// <summary>co-routine No.1</summary> static IEnumerable<string> Enumerate3() { for (; ; ) { yield return "one"; yield return "two"; yield return "three"; } } /// <summary>co-routine No.2</summary> static IEnumerable<string> Enumerate5() { for (; ; ) { yield return "いち"; yield return "に"; yield return "さん"; yield return "し"; yield return "ごー!"; } } }
単に手続きの中断と再開だけならIEnumerable