2017-12-04 4 views
0

수익률 반환을 사용하여 일부 데이터를 처리하고 비 결정적 반복을 사용합니다. 처리를 시작하고 싶지만 조건이 발생하면 (예 : 바이트 크기) 루프에서 빠져 나와 열거자를 처리를 계속할 새 스레드로 전달한 다음 지금까지 처리 된 결과를 반환합니다.C# yield return enumerator, 부분에서 계속 진행

사실 나는 끝나기 전에 돌발 할 가능성이있는 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 감사.

+0

좀 더 복잡한 항목 (현재 위치를 추적하는 유형)이 필요하거나 항목 수를 전달하여 다른 스레드에서 실행되는 코드로 건너 뛸 수 있습니다. – juharr

+2

@juharr : 아니요. 당신은 단지 열거자를 필요로합니다. – SLaks

+1

@SLaks 또는 그 다음, 당신은 당신이 그것을 적절하게 처분하는 것을 조심해야한다. – juharr

답변

4

실제로 IEnumerable<T> 인터페이스가 무엇을하는지보십시오.

IEnumerable<T>은 완전히 상태 비 저장됩니다. GetEnumerator() 메서드를 노출하기 만합니다.이 메서드는 stateful 열거자를 손으로 돌려서 그들이 어디에 있는지 추적합니다.

두 개의 루프 사이에 ator 인스턴스를 전달해야합니다. foreachIEnumerable<T> (또는 이와 유사)에서만 작동하므로 IEnumerator<T>을 직접 사용하는 while 루프로 대체해야합니다.

모든 코드 경로 (그렇지 않으면 finally 또는 using 블록이 실행되지 않습니다)에 IEnumerator을 폐기해야합니다.

-1

명세서가 자신의 ThreadFunc에 있는지 확인해야합니다! 주 기능에서 검사 할 때 스레드 기능이 중단되어 작동하지 않습니다.

관련 문제