AutoResetEvent não está bloqueando corretamente

Eu tenho um thread, que cria um número variável de threads de trabalho e distribui tarefas entre eles. Isso é resolvido passando os threads umTaskQueue objeto, cuja implementação você verá abaixo.

Esses threads de trabalho simplesmente iteram sobre oTaskQueue objeto que foram dados, executando cada tarefa.

private class TaskQueue : IEnumerable<Task>
{
    public int Count
    {
        get
        {
            lock(this.tasks)
            {
                return this.tasks.Count;
            }
        }
    }

    private readonly Queue<Task> tasks = new Queue<Task>();
    private readonly AutoResetEvent taskWaitHandle = new AutoResetEvent(false);

    private bool isFinishing = false;
    private bool isFinished = false;

    public void Enqueue(Task task)
    {
        Log.Trace("Entering Enqueue, lock...");
        lock(this.tasks)
        {
            Log.Trace("Adding task, current count = {0}...", Count);
            this.tasks.Enqueue(task);

            if (Count == 1)
            {
                Log.Trace("Count = 1, so setting the wait handle...");
                this.taskWaitHandle.Set();
            }
        }
        Log.Trace("Exiting enqueue...");
    }

    public Task Dequeue()
    {
        Log.Trace("Entering Dequeue...");
        if (Count == 0)
        {
            if (this.isFinishing)
            {
                Log.Trace("Finishing (before waiting) - isCompleted set, returning empty task.");
                this.isFinished = true;
                return new Task();
            }

            Log.Trace("Count = 0, lets wait for a task...");
            this.taskWaitHandle.WaitOne();
            Log.Trace("Wait handle let us through, Count = {0}, IsFinishing = {1}, Returned = {2}", Count, this.isFinishing);

            if(this.isFinishing)
            {
                Log.Trace("Finishing - isCompleted set, returning empty task.");
                this.isFinished = true;
                return new Task();
            }
        }

        Log.Trace("Entering task lock...");
        lock(this.tasks)
        {
            Log.Trace("Entered task lock, about to dequeue next item, Count = {0}", Count);
            return this.tasks.Dequeue();
        }
    }

    public void Finish()
    {
        Log.Trace("Setting TaskQueue state to isFinishing = true and setting wait handle...");
        this.isFinishing = true;

        if (Count == 0)
        {
            this.taskWaitHandle.Set();
        }
    }

    public IEnumerator<Task> GetEnumerator()
    {
        while(true)
        {
            Task t = Dequeue();
            if(this.isFinished)
            {
                yield break;
            }

            yield return t;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

Como você pode ver, estou usando umAutoResetEvent&nbsp;objeto para garantir que os threads de trabalho não saiam prematuramente, ou seja, antes de executar qualquer tarefa.

Em poucas palavras:

o encadeamento principal atribui uma tarefa a um encadeamentoEnqeueue-ing uma tarefa ao seu TaskQueueo encadeamento principal notifica o encadeamento que não há mais tarefas a serem executadas chamando o comando TaskQueueTerminar() métodoo encadeamento do trabalhador recupera a próxima tarefa atribuída a ele, chamando o comando TaskQueueRetirar da fila() método

O problema é que oRetirar da fila() frequentementelança uma InvalidOperationException, dizendo que a fila está vazia. Como você pode ver, eu adicionei alguns registros, e acontece queAutoResetEvent&nbsp;não bloqueia oRetirar da fila (), apesar de não haver chamadas para suaConjunto()&nbsp;método.

Pelo que entendi, chamar AutoResetEvent.Set () permitirá que um thread em espera prossiga (que anteriormente chamava AutoResetEvent.WaitOne ()) e depois chama automaticamente AutoResetEvent.Reset (), bloqueando o próximo garçom.

Então, o que pode estar errado? Eu entendi algo errado? Tenho algum erro em algum lugar? Estou sentado acima disso por 3 horas agora, mas não consigo descobrir o que há de errado. Por favor me ajude!

Muito obrigado!