ManualResetEvent против Thread.Sleep

Я реализовал следующий поток фоновой обработки, гдеJobs этоQueue<T>:

static void WorkThread()
{
    while (working)
    {
        var job;

        lock (Jobs)
        {
            if (Jobs.Count > 0)
                job = Jobs.Dequeue();
        }

        if (job == null)
        {
            Thread.Sleep(1);
        }
        else
        {
            // [snip]: Process job.
        }
    }
}

Это привело к заметной задержке между моментом ввода заданий и моментом их фактического запуска (пакеты заданий вводятся сразу, и каждое задание является только [относительно] небольшим.) Задержка не была огромной, но Я задумался над проблемой и сделал следующее изменение:

static ManualResetEvent _workerWait = new ManualResetEvent(false);
// ...
    if (job == null)
    {
        lock (_workerWait)
        {
            _workerWait.Reset();
        }
        _workerWait.WaitOne();
    }

Где поток, добавляющий рабочие места, теперь блокируется_workerWait и звонки_workerWait.Set() когда это будет сделано, добавление заданий. Это решение (казалось бы) мгновенно запускает обработку заданий, и задержка полностью исчезла.

Мой вопрос частично "Почему это происходит?", При условии, чтоThread.Sleep(int) может очень хорошо спать дольше, чем вы указываете, и частично "КакManualResetEvent достичь такого уровня производительности? ».

EDIT: Так как кто-то спросил о функции, которая ставит в очередь элементы, она здесь, вместе со всей системой, какой она есть в данный момент.

public void RunTriggers(string data)
{
    lock (this.SyncRoot)
    {
        this.Triggers.Sort((a, b) => { return a.Priority - b.Priority; });

        foreach (Trigger trigger in this.Triggers)
        {
            lock (Jobs)
            {
                Jobs.Enqueue(new TriggerData(this, trigger, data));
                _workerWait.Set();
            }
        }
    }
}

static private ManualResetEvent _workerWait = new ManualResetEvent(false);
static void WorkThread()
{
    while (working)
    {
        TriggerData job = null;

        lock (Jobs)
        {
            if (Jobs.Count > 0)
                job = Jobs.Dequeue();

            if (job == null)
            {
                _workerWait.Reset();
            }
        }

        if (job == null)
            _workerWait.WaitOne();
        else
        {
            try
            {
                foreach (Match m in job.Trigger.Regex.Matches(job.Data))
                    job.Trigger.Value.Action(job.World, m);
            }
            catch (Exception ex)
            {
                job.World.SendLineToClient("\r\n\x1B[32m -- {0} in trigger ({1}): {2}\x1B[m",
                    ex.GetType().ToString(), job.Trigger.Name, ex.Message);
            }
        }
    }
}

Ответы на вопрос(2)

Ваш ответ на вопрос