同步线程通信?

时间:2010-04-22 13:19:11

标签: c# multithreading jruby generator coroutine

只是为了它,我试图模仿JRuby生成器如何在C#中使用线程。

另外,我完全清楚C#已经内置了对收益率回报的支持,我只是在玩弄一下。

我认为通过使用线程保持多个callstack存活,这是一些糟糕的mans协程。 (即使没有任何一个callstack应该同时执行)

这个想法是这样的:

  • 使用者线程请求值
  • 工作线程提供一个值并返回到使用者线程
  • 重复直到工作线程完成

那么,执行以下操作的正确方法是什么?

//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 :(得分:0)

在C#中实现生产者/消费者模式的方法有很多种。 我猜,最好的方法是使用TPL(Task,BlockingCollection)。查看示例here