2013/01/03

Producer-Consumer 問題

スレッドからスレッドへと、次々にデータを受け渡すときに必要になるのがこれ。

描画スレッドを別スレッドに移動させるときに必要だったのでござる。http://www.atmarkit.co.jp/fdotnet/mthread/mthread04/mthread04_02.html の例をジェネリクスにしただけでござる。

class BoundedBuffer<T> : IDisposable
    where T: IDisposable
{
    public int Max { get; private set; }
    public int Count
    {
        get
        {
            lock (lockObject)
            {
                return queue.Count;
            }
        }
    }

    private Queue<T> queue;
    private object lockObject = new object();


    public BoundedBuffer(int maxCount)
    {
        this.Max = maxCount;
        this.queue = new Queue<T>(Max);
    }

    public void Enqueue(T value)
    {
        Monitor.Enter(lockObject);
        try
        {
            while (queue.Count >= Max)
            {
                Monitor.Wait(lockObject);
            }
            queue.Enqueue(value);
            Monitor.PulseAll(lockObject);
        }
        catch
        {
        }
        finally
        {
            Monitor.Exit(lockObject);
        }
    }

    public T Dequeue()
    {
        Monitor.Enter(lockObject);
        T result = default(T);
        try
        {
            while (!queue.Any())
            {
                Monitor.Wait(lockObject);
            }
            result = queue.Dequeue();
            Monitor.PulseAll(lockObject);
        }
        catch (Exception e)
        {

        }
        finally
        {
            Monitor.Exit(lockObject);
        }

        return result;
    }

    public void Dispose()
    {
        lock (lockObject)
        {
            T value;
            while ((value = queue.Dequeue()) != null)
            {
                value.Dispose();
            }
        }
    }
}

そのものずばりの解答を見ているとはいえ、上手く動いてくれると気持ち良いでござる。

0 件のコメント:

コメントを投稿