코루틴을 잘 이용하면 개별 상태에 대한 처리를 코드 가독성을 높이면서 처리할 수 있는데요, C#은 yield
를 이용해 이를 달성할 수 있습니다.
흥미로운 점은 C#가 IEnumerable
과 IEnumerator
인터페이스를 제공한다는 점입니다. IEnumerable
인터페이스는 단지 IEnumerator
를 반환하는데요, 일반화된 IEnumerable
인터페이스에 의해 개별 코루틴을 호출하는 대상은 구체적인 유형을 알 필요가 없습니다.
yield
구문을 사용하는 루틴은 코루틴이 되는데, IEnumerable
또는 IEnumerator
인스턴스에 따라 루틴의 상태 값을 별도로 가질 수 있기 때문입니다.
var runnerGenerator = GetRunnerGenerator();
var runners = new List<IEnumerator<int>>();
for (var i = 0; i < 5; i++)
runners.Add(runnerGenerator.GetEnumerator());
bool bFound;
do
{
bFound = false;
var number = 0;
foreach (var runner in runners)
{
number++;
if (runner.MoveNext() == false)
continue;
bFound = true;
var running = runner.Current;
Console.WriteLine($"Runner #{number}: {running}");
}
}
while (bFound == true);
IEnumerable<int> GetRunnerGenerator()
{
var count = new Random().Next(1, 10);
Console.WriteLine($"Start Running: {count}");
for (var i = 1; i <= count; i++)
yield return i;
}
Start Running: 3
Runner #1: 1
Start Running: 1
Runner #2: 1
Start Running: 1
Runner #3: 1
Start Running: 4
Runner #4: 1
Start Running: 5
Runner #5: 1
Runner #1: 2
Runner #4: 2
Runner #5: 2
Runner #1: 3
Runner #4: 3
Runner #5: 3
Runner #4: 4
Runner #5: 4
Runner #5: 5
간단하게 만들어본 예제, yield
구문을 사용한 GetRunnerGenerator()
메소드는 생성된 인스턴스 별 count
라는 값과 변화되는 i
값을 개별 가지는 것을 확인할 수 있는데요, 코드의 흐름은 순차적이라 코드 가독성이 좋습니다.
관련해서 사용 경험이 있으시거나 궁금한 점, 여러가지 아이디어 댓글로 달아주세요!