2010-04-22 4 views
1

JRuby 생성기가 C#의 쓰레드를 사용하여 어떻게 동작하는지 에뮬레이트하려고합니다.스레드 통신 동기화 중입니까?

또한 C#이 수익률 반환을 지원한다는 사실을 충분히 알고 있습니다.

필자는 스레드를 사용하여 여러 callstacks를 유지함으로써 가독성이 낮은 coroutines라고 생각합니다. 생각이 같다

을 (호출 스택의 어느 것도 동시에 실행 안하더라도) :

소비자 스레드는 작업자 스레드가 값을 제공하고 다시 산출
  • 값을 요청
    • 소비자 스레드
    • 반복 전까지 작업자 스레드는 무엇 다음을 수행의 올바른 방법이 될, 그래서

  • 을 것입니다 이루어집니다?

    //example 
    class Program 
    { 
        static void Main(string[] args) 
        { 
         ThreadedEnumerator<string> enumerator = new ThreadedEnumerator<string>(); 
    
         enumerator.Init(() => 
          { 
           for (int i = 1; i < 100; i++) 
           { 
            enumerator.Yield(i.ToString()); 
           } 
          }); 
    
         foreach (var item in enumerator) 
         { 
          Console.WriteLine(item); 
         }; 
    
         Console.ReadLine(); 
        } 
    } 
    
    //naive threaded enumerator 
    public class ThreadedEnumerator<T> : IEnumerator<T>, IEnumerable<T> 
    { 
        private Thread enumeratorThread; 
        private T current; 
        private bool hasMore = true; 
        private bool isStarted = false; 
        AutoResetEvent enumeratorEvent = new AutoResetEvent(false); 
        AutoResetEvent consumerEvent = new AutoResetEvent(false); 
        public void Yield(T item) 
        { 
         //wait for consumer to request a value 
         consumerEvent.WaitOne(); 
    
         //assign the value 
         current = item; 
    
         //signal that we have yielded the requested 
         enumeratorEvent.Set(); 
        } 
    
        public void Init(Action userAction) 
        { 
         Action WrappedAction =() => 
         { 
          userAction(); 
          consumerEvent.WaitOne(); 
          enumeratorEvent.Set(); 
          hasMore = false; 
         }; 
         ThreadStart ts = new ThreadStart(WrappedAction); 
         enumeratorThread = new Thread(ts); 
         enumeratorThread.IsBackground = true; 
         isStarted = false; 
        } 
    
        public T Current 
        { 
         get { return current; } 
        } 
    
        public void Dispose() 
        { 
         enumeratorThread.Abort(); 
        } 
    
        object System.Collections.IEnumerator.Current 
        { 
         get { return Current; } 
        } 
    
        public bool MoveNext() 
        { 
         if (!isStarted) 
         { 
          isStarted = true; 
          enumeratorThread.Start(); 
         } 
         //signal that we are ready to receive a value 
         consumerEvent.Set(); 
    
         //wait for the enumerator to yield 
         enumeratorEvent.WaitOne(); 
    
         return hasMore; 
        } 
    
        public void Reset() 
        { 
         throw new NotImplementedException(); 
        } 
    
        public IEnumerator<T> GetEnumerator() 
        { 
         return this; 
        } 
    
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
        { 
         return this; 
        } 
    } 
    

    아이디어가 있습니까?

    +1

    코드가 전체적으로 올바로 보입니다. 나는 너무 많은 시간을주지는 않았지만 약간의 버그가있을 수 있지만 전반적으로 좋아 보인다. 문제가 있습니까? 질문이 뭐야? –

    +0

    기본 질문은 다음과 같습니다. C# yield return 상태 머신을 내장하여 동일한 승/O를 수행하는 더 좋은 방법이 있습니까? 코드와 관련하여 경우에 따라 중단되며 열거자를 중첩하면 매우 잘 수행되지 않습니다. 나는 쓰레딩에 관해서는 우둔한 것이므로 무엇을 더해야할지 잘 모른다. –

    답변

    0

    C#에서 생성자/소비자 패턴을 구현하는 데는 여러 가지 방법이 있습니다. 가장 좋은 방법은 TPL (Task, BlockingCollection)을 사용하는 것입니다. 예 here을 참조하십시오.