C# 코루틴의 고찰

코루틴을 잘 이용하면 개별 상태에 대한 처리를 코드 가독성을 높이면서 처리할 수 있는데요, C#은 yield를 이용해 이를 달성할 수 있습니다.

흥미로운 점은 C#가 IEnumerableIEnumerator 인터페이스를 제공한다는 점입니다. 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 값을 개별 가지는 것을 확인할 수 있는데요, 코드의 흐름은 순차적이라 코드 가독성이 좋습니다.

관련해서 사용 경험이 있으시거나 궁금한 점, 여러가지 아이디어 댓글로 달아주세요!

5개의 좋아요